在Hibernate教程中添加CONSTRAINT

时间:2016-03-04 06:32:54

标签: java hibernate jboss

这个例子来自JBOSS的hibernate教程。链接在那里: http://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#embeddables

示例79.单向@OneToMany关联

private static String[] splitRegex(String input, String regex) {
    String[] splitString=  input.split("((?<=" + regex + ")|(?=" + regex + "))");
    if (splitString.length>1){
        return splitString;
    }else {
        return new String[]{};
    }
}

我的问题是,在这个例子中:

1)为什么ADD CONSTRAINT看起来像机器生成的字符串,&#34; FKr38us2n8g5p9rj0b494sd3391&#34;?不应该用更有意义的约束手动创建吗?

2)在这种情况下,ADD CONSTRAINT是可选的吗?

2 个答案:

答案 0 :(得分:1)

  

为什么ADD CONSTRAINT看起来像机器生成的字符串,   “FKr38us2n8g5p9rj0b494sd3391”?不应该用a手动创建   更有意义的约束?

当然,数据库不会生成约束。它由Hibernate生成。

由于某些数据库中的约束名称长度限制,生成了这个奇怪的名称FKr38us2n8g5p9rj0b494sd3391。例如,在Oracle数据库中,它的长度不能超过30个符号。

Hibernate通过连接表和属性名称生成约束名称,并将结果转换为MD5,生成FKr38us2n8g5p9rj0b494sd3391之类的字符串。这段来自Hibernate源代码片段

/**
 * 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 hashed name.
 */
public 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 name!", e );
    }
}

您可以使用ImplicitNamingStrategy生成自己的约束名称(唯一键和外键)。您可以参考Hibernate5NamingStrategy 作为示例。

另外,要指定约束名称(通常情况下),您可以使用@ForeignKey@JoinColumn注释。

如果是联接表,您可以使用@JoinTable注释,如@uditkhare建议的那样。但是你需要提供更多的信息(这不是很方便)

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinTable(name="person_phones", 
    joinColumns = @JoinColumn(name = "f_person_pid", foreignKey = @ForeignKey(
            name = "fk_person_phones_person")), 
    inverseJoinColumns = @JoinColumn(name = "fk_phone",
            foreignKey = @ForeignKey(name = "fk_person_phones_phone")),
            uniqueConstraints = @UniqueConstraint(name = "uk_person_phones_phone",
            columnNames = { "fk_phone" }))
private List<Phone> phones = new ArrayList<>();
  

在这种情况下,ADD CONSTRAINT是可选的吗?

没有。它不是可选的。需要建模@OneToMany关系。

答案 1 :(得分:0)

是的,仅由hibernate生成。

如果您想自己定义,可以使用以下内容:

@OneToMany
@JoinTable(uniqueConstraints=@UniqueConstraint(name="my_unique_key", columnNames={"phones_id"}))