我有以下具有一对一映射的关联类。
@Entity
public class EmployeeEntity
{
@Id
private String id;
private String name;
@OneToOne(mappedBy = "employeeEntity", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@Fetch(FetchMode.SELECT)
@JoinColumn(name = "empid")
private AddressEntity addressEntity;
...
...
getters & setters
}
@Entity
public class AddressEntity
{
@Id
@Column(unique=true, nullable=false)
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign", parameters=@Parameter(name="property", value="employeeEntity"))
private String empId;
@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private EmployeeEntity employeeEntity;
...
getters & setters
}
我正在使用 postgres 并且有表(员工实体,地址实体),地址实体表上有以下外键约束: 外键约束: "fkakhilesh"FOREIGN KEY (empid) REFERENCES employeeentity(id) ON DELETE CASCADE
我对不同的 REST 调用有以下要求:
- POST 休息电话 - 应该创建一个有地址的员工。
- POST 休息电话 - 应该创建一个没有地址的员工。
- GET Rest 调用 - 应该找回员工。如果存在地址,也应附上。
- PUT 休息电话 - 应更新员工和地址(如果地址存在)。
- PUT Rest call - 应该更新员工和地址(本地址被传递并且它已经存在于 empid 的地址实体表中时)
- PUT 休息调用 - 应该更新员工并创建地址(本地址被传递并且它不存在于 empid 的地址实体表中时)
我能够毫无问题地执行操作 1 到 5。
主要问题在 6 中,我想到了以下问题: 1. 当我执行“getSession().update(object)”时,我得到 hibernate 状态的 StaleStateException:批量更新从更新 [0] 返回了意外的行数;实际行数:0;预期:1。 如果地址不存在,“更新”是不可能的吗?我不能在更新期间创建新地址吗?
我是否需要将 ServiceImpl 调用更改为“getSession().merge(object)”?这种情况是否只能通过调用“merge”来处理?它对性能有何影响?
如果我进行合并,我会得到 hibernate 的 IdentifierGenerationException:试图从 null 一对一属性分配 id。 我在这里错过了什么吗?
这可以通过更改 hibernate 映射来解决吗?或者与级联有关的东西。
这里 @GeneratedValue(generator="gen") 的重要性是什么?为什么在@GenericGenerator中使用@parameter
我是 hibernate 的新手,正在尝试深入了解 hibernate 映射。 另外,如果您能就设计向我提出建议,我将很高兴,因为这应该是处理此问题的最佳方法。
最佳答案
我已经解决了这个问题。这种一对一的映射有点棘手,并不像我最初想象的那样简单。 我使用了双向一对一映射,因此在更新期间调用 EmployeeEntity 和 AddressEntity 的 setter 来相互设置是很重要的。例如:
employeeEntity.setAddressEntity(addressEntity) 和 addressEntity.setEmpoyeeEntity(empoyeeEntity) 必须显式调用。
单独设置 employeeEntity.setAddressEntity(addressEntity) 是行不通的。
关于java - hibernate 一对一映射不更新子表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14878026/