2016-04-21 124 views
1

hibernate如何生成外鍵約束名稱?hibernate如何生成外鍵約束名稱?

如果我不定義一個名字休眠產生這樣的

CONSTRAINT fk_2ocepcfwpr1v18dg1ieoe6bau 

是如何產生這個名字呢?也許從MD5字段名稱的哈希或類似的東西?我需要知道在所有情況下名稱是否相同。

回答

4

Hibernate通過連接表和屬性名稱來生成約束名稱,並將結果轉換爲MD5。由於某些數據庫中的約束名稱長度限制,它是必需的。例如,在Oracle數據庫中,外鍵名稱長度不能超過30個符號長度。

由Hibernate源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); 
    } 
} 

這段代碼可以使用ImplicitNamingStrategy生成自己的約束名稱(唯一性和外鍵)。作爲一個例子,你可以參考Hibernate5NamingStrategy