在Hibernate教程中添加CONSTRAINT
这个例子来自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 phones = new ArrayList(); public Person() { } public List 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)为什么ADD CONSTRAINT看起来像机器生成的字符串,“FKr38us2n8g5p9rj0b494sd3391”? 它不应该用更有意义的约束手动创建吗?
2)在这种情况下,ADD CONSTRAINT是否可选?
为什么ADD CONSTRAINT看起来像机器生成的字符串,“FKr38us2n8g5p9rj0b494sd3391”? 它不应该用更有意义的约束手动创建吗?
当然,约束不是由数据库生成的。 它由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 phones = new ArrayList<>();
在这种情况下,ADD CONSTRAINT是可选的吗?
不,它不是可选的。 需要建模@OneToMany
关系。
是的,仅由hibernate生成。
如果您想自己定义,可以使用以下内容:
@OneToMany @JoinTable(uniqueConstraints=@UniqueConstraint(name="my_unique_key", columnNames={"phones_id"}))
- Hibernate更快地创建EntityManagerFactory
- 理解注释和JPA(hibernate)
- 由于Bean Validation API而无法启动Hibernate Validator
- Netbeans Hibernate映射文件中的NullPointerException和Firebird数据库中的POJO向导
- hibernate是否保留LinkedHashSet的顺序,如果是,如何?
- 如何在Tomcat中使用Hibernate支持的JPA运行Spring 3.0 PetClinic
- Hibernate和mysql的连接太多了
- Hibernate Bi-Directional多对多关联创建重复
- 线程“main”中的exceptionorg.hibernate.HibernateException:访问stax流时出错