【问题标题】:How does hibernate generate foreign key constraint names?hibernate如何生成外键约束名?
【发布时间】:2016-08-14 11:48:53
【问题描述】:

hibernate如何生成外键约束名?

如果我没有定义名称,hibernate 会生成类似这样的内容

CONSTRAINT fk_2ocepcfwpr1v18dg1ieoe6bau

这个名字是怎么产生的?也许来自MD5 字段名称的哈希或类似的东西?我需要知道名称是否在所有实例上都相同。

【问题讨论】:

    标签: hibernate hbm2ddl


    【解决方案1】:

    Hibernate 通过连接表名和属性名生成一个约束名,并将结果转换为MD5。由于某些数据库中的约束名称长度限制,因此需要它。例如,在 Oracle 数据库中,外键名称长度不能超过 30 个符号长度。

    这段代码sn-p来自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 ,例如。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 2015-11-16
      • 2018-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多