Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does hibernate generate foreign key constraint names?

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.

like image 752
wutzebaer Avatar asked Apr 21 '16 10:04

wutzebaer


People also ask

Which annotation is used for foreign key in hibernate?

7.2. This foreign key is referred to as the collection key column, or columns, of the collection table. The collection key column is mapped by the @JoinColumn annotation respectively the <key> XML element. In annotations the Hibernate specific annotation @OnDelete has to be used.

How do you make a foreign key a primary key in hibernate?

You can use JPA's @MapsId annotation to tell Hibernate that it shall use the foreign key of an associated entity as the primary key. Let's take a look at a simple example. Each Book has a Manuscript, and each Manuscript belongs to 1 Book. The foreign key of the Book is also the primary key of the Manuscript.

Does foreign key create index MySQL?

MySQL requires that foreign key columns be indexed; if you create a table with a foreign key constraint but no index on a given column, an index is created.


1 Answers

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.

like image 85
v.ladynev Avatar answered Sep 19 '22 17:09

v.ladynev