我正在尝试使用Hibernate中的一对一映射,我感到很困惑。我通过一对一关系有两个表Student和Address映射,并为Address表设置外键。我创建了一个将数据保存到数据库的函数,如下所示:
public static void oneToOneMappingWithXML(Session session) throws Exception {
StudentEntity tom = new StudentEntity();
tom.setName("Tom");
tom.setAge(10);
tom.setClazz("5B");
tom.setStudentId(1);
AddressEntity tom_address = new AddressEntity();
tom_address.setCity("New York");
tom_address.setAddressId(1);
tom.setAddressByStudentId(tom_address);
//tom_address.setStudentByAddressId(tom); //#1
session.save(tom);
session.getTransaction().commit();
}
这是我的映射:
<class name="com.model.xmlType.AddressEntity" table="ADDRESS" schema="CHINOOK">
<id name="addressId">
<column name="ADDRESS_ID" sql-type="number(10)" precision="10"/>
</id>
<property name="city">
<column name="CITY" sql-type="nvarchar2(50)" length="50"/>
</property>
<one-to-one name="studentByAddressId" class="com.model.xmlType.StudentEntity"/>
</class>
<class name="com.model.xmlType.StudentEntity" table="STUDENT" schema="CHINOOK">
<id name="studentId">
<column name="STUDENT_ID" sql-type="number(10)" precision="10"/>
</id>
<property name="name">
<column name="NAME" sql-type="nvarchar2(50)" length="50"/>
</property>
<property name="age">
<column name="AGE" sql-type="number(10)" precision="10"/>
</property>
<property name="clazz">
<column name="CLASS" sql-type="nvarchar2(10)" length="10"/>
</property>
<one-to-one name="addressByStudentId" class="com.model.xmlType.AddressEntity" cascade="all"/>
实体类
学生:
public class StudentEntity {
private Integer studentId;
private String name;
private Integer age;
private String clazz;
private AddressEntity addressByStudentId;
public Integer getStudentId() {
return studentId;
}
public void setStudentId(Integer studentId) {
this.studentId = studentId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getClazz() {
return clazz;
}
public void setClazz(String clazz) {
this.clazz = clazz;
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StudentEntity that = (StudentEntity) o;
if (studentId != null ? !studentId.equals(that.studentId) : that.studentId != null) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
if (age != null ? !age.equals(that.age) : that.age != null) return false;
if (clazz != null ? !clazz.equals(that.clazz) : that.clazz != null) return false;
return true;
}
public int hashCode() {
int result = studentId != null ? studentId.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (age != null ? age.hashCode() : 0);
result = 31 * result + (clazz != null ? clazz.hashCode() : 0);
return result;
}
public AddressEntity getAddressByStudentId() {
return addressByStudentId;
}
public void setAddressByStudentId(AddressEntity addressByStudentId) {
this.addressByStudentId = addressByStudentId;
}
}
地址:
public class AddressEntity {
private Integer addressId;
private String city;
private StudentEntity studentByAddressId;
public Integer getAddressId() {
return addressId;
}
public void setAddressId(Integer addressId) {
this.addressId = addressId;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AddressEntity that = (AddressEntity) o;
if (addressId != null ? !addressId.equals(that.addressId) : that.addressId != null) return false;
if (city != null ? !city.equals(that.city) : that.city != null) return false;
return true;
}
@Override
public int hashCode() {
int result = addressId != null ? addressId.hashCode() : 0;
result = 31 * result + (city != null ? city.hashCode() : 0);
return result;
}
public StudentEntity getStudentByAddressId() {
return studentByAddressId;
}
public void setStudentByAddressId(StudentEntity studentByAddressId) {
this.studentByAddressId = studentByAddressId;
}
}
它的工作非常顺利,两个实体都得到了保存。但是当第1行被取消注释时,只有实体Student才会保存。代码如下:
public static void oneToOneMappingWithXML(Session session) throws Exception {
StudentEntity tom = new StudentEntity();
tom.setName("Tom");
tom.setAge(10);
tom.setClazz("5B");
tom.setStudentId(1);
AddressEntity tom_address = new AddressEntity();
tom_address.setCity("New York");
tom_address.setAddressId(1);
tom.setAddressByStudentId(tom_address);
tom_address.setStudentByAddressId(tom); //#1
session.save(tom);
session.getTransaction().commit();
}
我不知道为什么。那么,有人可以向我解释一下吗?
答案 0 :(得分:0)
请注意,仅在一侧设置引用时,Hibernate不会自动使对象引用成双向。因此,你必须确保在双向引用上,两个方面在保持之前都能正确设置。
尝试将实体看作数据库中的记录而不是对象。如果对象“汤姆”没有“知道”他甚至有一个地址,并且要求“汤姆”坚持自己,那么“汤姆”怎么能坚持他的地址?
(事实上,你可以保存“tom”而没有地址,然后保存一个引用“tom”的地址;然后,如果你重新加载“tom”,他会突然有一个地址,因为数据库中的 ,关系的方向并不重要。但你不应该这样做。)
始终在两侧正确初始化您的双向参考,您应该是好的。
答案 1 :(得分:0)
session.save(tom_address);
session.save(tom);
session.getTransaction().commit();
在保存学生之前保存地址。