【问题标题】:How can I remove an object with a foreign primary key in JPA?如何在 JPA 中删除具有外主键的对象?
【发布时间】:2017-03-18 10:27:01
【问题描述】:

我总是被告知,在双向关系的情况下,您删除您的实体如下:

  1. 细分关系
  2. 更新所有者实体
  3. 删除实体

但是现在我的主键是关系的一部分,所以这不再可能了。

有没有人知道在这种情况下如何删除具有主外键的实体?

我尝试将“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)与主键(或应该)相同

也许这可以帮助遇到相同问题的人,直到找到实际的解决方案。

【问题讨论】:

  • 不清楚您使用 MapsId 注释的目的。您只是想将这种关系标记为@Id 吗?这将允许 OrderBill 使用 OrderWeekPK 作为它的 pkClass。
  • @Chris 只是将该字段标记为外键,表示该字段使用OrderWeek的pk。 (This 站点可能会更好地解释它)但是很明显,我没有意识到我没有在我的代码 sn-p 中为 OrderBill 放置一个 \@embeddedid。这个错误可能让很多人感到困惑,将立即编辑。

标签: java jpa entity eclipselink


【解决方案1】:

您可以通过在 orderWeek 属性上使用 @Id 并在实体上指定 @IdClass(OrderWeekPK.class) 来取消 @MapsId 并嵌入在 OrderBill 中 - 这可能适用于您的映射,但不是不是您在帖子中提到的错误的来源。

问题是您有两个具有双向关系的实体。如果您更改了关系(例如 null it out),则需要将此更改合并到上下文中。因此,要删除 OrderBill 实例,您必须在实例上调用 em.remove 并将 OrderWeek 引用清空,然后在 OrderWeek 上调用 merge。这需要在同一个事务中完成,虽然对 OrderWeek 的 orderBill 引用的更改在数据库中是无操作的,但它将保持缓存不同步并防止 OrderBill 被复活(或您看到的异常)

另一种方法是将孤立删除标记添加到 OrderWeek 的 orderBill 属性中,如果您取消此引用,这会导致 JPA 自动调用 em.remove。

【讨论】:

    猜你喜欢
    • 2019-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-02
    • 2017-04-28
    • 2011-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多