总是告诉我,在双向关系的情况下,您可以按以下方式删除实体:
细分关系
更新所有者实体
移除实体
但是现在我的主键是关系的一部分,所以这不可能了。
在这种情况下,是否有人知道如何使用主外键删除实体?
我试图将“ mappedby”属性设置为null,而不是仅调用manager.remove(...),但是总会有另一个实体管理器仍然具有已删除实体的托管实例,因此出现以下错误:
During synchronization a new object was found through a relationship
that was not marked cascade PERSIST
我在下面放了我正在使用的类的代码。
此处的类
OrderBill
具有指向OrderWeek
的主外键。这个主键也是一个复合键,可悲的是使代码的可读性降低了一些,但是它对我遇到的问题没有任何影响。public class OrderBill{
@EmbeddedId
private OrderWeekPK orderWeekPK;
@OneToOne
@JoinColumns(value = {
@JoinColumn(name="weekNr", referencedColumnName = "weekNr"),
@JoinColumn(name="yearNr", referencedColumnName = "yearNr")})
@MapsId
private OrderWeek orderWeek;
}
public class OrderWeek{
@OneToOne(mappedBy="orderWeek")
private OrderBill orderBill;
@EmbeddedId
private OrderWeekPK orderWeekPK;
}
@Embeddable
public class OrderWeekPK implements Serializable{
@Column(name="yearNr")
private int yearNr;
@Column(name="weekNr")
private int weekNr;
}
是否有一些我缺少的策略?
更新:现在,我可以通过切换拥有和拥有的一面(将mappedby转移到
OrderBill
类)来解决此问题。现在,我可以在不触摸外键的情况下中断关系。此“解决方案”仍然不理想:
OrderWeek
现在具有一个冗余列(例如,weekNr2和yearNr2),该列(或应该)与主键相同也许这会帮助有相同问题的人找到实际的解决方案。
最佳答案
您可以通过在orderWeek属性上使用@Id并在实体上指定@IdClass(OrderWeekPK.class)来取消@MapsId和可嵌入到OrderBill中的功能-这可能对您的映射有效,但不是您在帖子中提到的错误的来源。
问题是您有两个具有双向关系的实体。如果更改关系(例如将其清空),则需要将此更改合并到上下文中。因此,要删除OrderBill实例,您必须在实例上调用em.remove,并使OrderWeek引用无效,然后在OrderWeek上调用merge。这需要在同一事务中完成,并且对OrderWeek的orderBill引用所做的更改是数据库中的禁忌操作,但它将使高速缓存保持异步状态并防止OrderBill被复活(或您看到的异常)
另一种方法是将孤立删除标记添加到OrderWeek的orderBill属性中,如果您将此引用无效,JPA将自动调用em.remove。
关于java - 如何在JPA中删除带有外键的对象?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40425179/