此示例来自JBOSS的hibernate教程。该链接位于:http : //docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#embeddables。
例子79.单向的@OneToMany关联
@Entity(name = "Person") public static class Person { @Id @GeneratedValue private Long id; @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) private List<Phone> phones = new ArrayList<>(); public Person() { } public List<Phone> getPhones() { return phones; } } @Entity(name = "Phone") public static class Phone { @Id @GeneratedValue private Long id; private String number; public Phone() { } public Phone(String number) { this.number = number; } public Long getId() { return id; } public String getNumber() { return number; } } CREATE TABLE Person ( id BIGINT NOT NULL , PRIMARY KEY ( id ) ) CREATE TABLE Person_Phone ( Person_id BIGINT NOT NULL , phones_id BIGINT NOT NULL ) CREATE TABLE Phone ( id BIGINT NOT NULL , number VARCHAR(255) , PRIMARY KEY ( id ) ) ALTER TABLE Person_Phone ADD CONSTRAINT UK_9uhc5itwc9h5gcng944pcaslf UNIQUE (phones_id) ALTER TABLE Person_Phone ADD CONSTRAINT FKr38us2n8g5p9rj0b494sd3391 FOREIGN KEY (phones_id) REFERENCES Phone ALTER TABLE Person_Phone ADD CONSTRAINT FK2ex4e4p7w1cj310kg2woisjl2 FOREIGN KEY (Person_id) REFERENCES Person
我的问题是,在此示例中:
1)为什么添加约束看起来像机器生成的字符串“ FKr38us2n8g5p9rj0b494sd3391”?难道不是应该在一个更有意义的约束下手动创建它吗?
2)在这种情况下,ADD CONSTRAINT是可选的吗?
为什么添加约束看起来像机器生成的字符串“ FKr38us2n8g5p9rj0b494sd3391”?难道不是应该在一个更有意义的约束下手动创建它吗?
当然,约束不是由数据库生成的。它是由Hibernate生成的。
FKr38us2n8g5p9rj0b494sd3391由于某些数据库中的约束名称长度受到限制,因此生成了这个奇怪的名称。例如,在Oracle数据库中,其长度不能超过30个符号。
FKr38us2n8g5p9rj0b494sd3391
Hibernate通过连接表和属性名称来生成约束名称,并将结果转换为MD5,生成类似的字符串FKr38us2n8g5p9rj0b494sd3391。该代码段来自Hibernate源代码
MD5
/** * 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作为示例。
ImplicitNamingStrategy
另外,还可以使用@ForeignKey和@JoinColumn注释来指定约束名称(在通常情况下)。
@ForeignKey
@JoinColumn
对于@JoinTable联接表,可以使用注释,如@uditkhare建议的那样。但是您需要提供更多信息(不是很方便)
@JoinTable
@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关系模型。
@OneToMany