How does hibernate generate foreign key constraint names?

两盒软妹~` 提交于 2020-01-13 05:52:31

问题


How does hibernate generate foreign key constraint names?

If i do not define a name hibernate generates something like this

CONSTRAINT fk_2ocepcfwpr1v18dg1ieoe6bau

how is this name generated? Maybe from MD5 hash of field names or something like that? I need to know if the name is equal on all instances.


回答1:


Hibernate generates a constraint name by concatenating table and properties names and convert the result to MD5. It is needed, because of the constraint names length restriction in some databases. For an example, in the Oracle database, a foreign key name length can't be more than 30 symbols length.

This code snippet from Hibernate source org.hibernate.mapping.Constraint

/**
 * If a constraint is not explicitly named, this is called to generate
 * a unique hash using the table and column names.
 * Static so the name can be generated prior to creating the Constraint.
 * They're cached, keyed by name, in multiple locations.
 *
 * @return String The generated name
 */
public static String generateName(String prefix, Table table, Column... columns) {
    // Use a concatenation that guarantees uniqueness, even if identical names
    // exist between all table and column identifiers.

    StringBuilder sb = new StringBuilder( "table`" + table.getName() + "`" );

    // Ensure a consistent ordering of columns, regardless of the order
    // they were bound.
    // Clone the list, as sometimes a set of order-dependent Column
    // bindings are given.
    Column[] alphabeticalColumns = columns.clone();
    Arrays.sort( alphabeticalColumns, ColumnComparator.INSTANCE );
    for ( Column column : alphabeticalColumns ) {
        String columnName = column == null ? "" : column.getName();
        sb.append( "column`" ).append( columnName ).append( "`" );
    }
    return prefix + hashedName( sb.toString() );
}

/**
 * Hash a constraint name using MD5. Convert the MD5 digest to base 35
 * (full alphanumeric), guaranteeing
 * that the length of the name will always be smaller than the 30
 * character identifier restriction enforced by a few dialects.
 * 
 * @param s
 *            The name to be hashed.
 * @return String The hased name.
 */
public static String hashedName(String s) {
    try {
        MessageDigest md = MessageDigest.getInstance( "MD5" );
        md.reset();
        md.update( s.getBytes() );
        byte[] digest = md.digest();
        BigInteger bigInt = new BigInteger( 1, digest );
        // By converting to base 35 (full alphanumeric), we guarantee
        // that the length of the name will always be smaller than the 30
        // character identifier restriction enforced by a few dialects.
        return bigInt.toString( 35 );
    }
    catch ( NoSuchAlgorithmException e ) {
        throw new HibernateException( "Unable to generate a hashed Constraint name!", e );
    }
}

You can generate your own constraint names (unique and foreign key) using ImplicitNamingStrategy. You can refer Hibernate5NamingStrategy , as an example.



来源:https://stackoverflow.com/questions/36766848/how-does-hibernate-generate-foreign-key-constraint-names

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!