在 Hibernate 教程中添加约束
ADD CONSTRAINT in Hibernate tutorial
这个例子来自 JBOSS 的休眠教程。 link 在那里:
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) 为什么 ADD CONSTRAINT 看起来像机器生成的字符串,"FKr38us2n8g5p9rj0b494sd3391"?不应该使用更有意义的约束手动创建它吗?
2) 在这种情况下 ADD CONSTRAINT 是可选的吗?
是的,仅由休眠生成。
如果你想自己定义这些,你可以使用下面的东西:
@OneToMany
@JoinTable(uniqueConstraints=@UniqueConstraint(name="my_unique_key", columnNames={"phones_id"}))
Why does the ADD CONSTRAINT looks like a machine generated string,
"FKr38us2n8g5p9rj0b494sd3391"? Shouldn't it be created manually with a
more meaningful constraint?
当然,约束不是由数据库生成的。它由 Hibernate 生成。
这个奇怪的名字FKr38us2n8g5p9rj0b494sd3391
是由于某些数据库中的约束名称长度限制而产生的。例如,在 Oracle 数据库中,它不能超过 30 个符号长度。
Hibernate 通过连接 table 和 属性 名称生成约束名称并将结果转换为 MD5
,生成类似 FKr38us2n8g5p9rj0b494sd3391
的字符串。此代码片段来自 Hibernate source
/**
* 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
注释来指定约束名称(通常情况下)。
在连接 table 的情况下,您可以使用 @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<>();
Is the ADD CONSTRAINT optional in this case?
没有。它不是可选的。需要对 @OneToMany
关系建模。
这个例子来自 JBOSS 的休眠教程。 link 在那里: 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) 为什么 ADD CONSTRAINT 看起来像机器生成的字符串,"FKr38us2n8g5p9rj0b494sd3391"?不应该使用更有意义的约束手动创建它吗?
2) 在这种情况下 ADD CONSTRAINT 是可选的吗?
是的,仅由休眠生成。
如果你想自己定义这些,你可以使用下面的东西:
@OneToMany
@JoinTable(uniqueConstraints=@UniqueConstraint(name="my_unique_key", columnNames={"phones_id"}))
Why does the ADD CONSTRAINT looks like a machine generated string, "FKr38us2n8g5p9rj0b494sd3391"? Shouldn't it be created manually with a more meaningful constraint?
当然,约束不是由数据库生成的。它由 Hibernate 生成。
这个奇怪的名字FKr38us2n8g5p9rj0b494sd3391
是由于某些数据库中的约束名称长度限制而产生的。例如,在 Oracle 数据库中,它不能超过 30 个符号长度。
Hibernate 通过连接 table 和 属性 名称生成约束名称并将结果转换为 MD5
,生成类似 FKr38us2n8g5p9rj0b494sd3391
的字符串。此代码片段来自 Hibernate source
/**
* 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
注释来指定约束名称(通常情况下)。
在连接 table 的情况下,您可以使用 @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<>();
Is the ADD CONSTRAINT optional in this case?
没有。它不是可选的。需要对 @OneToMany
关系建模。