【问题标题】:Why do I need to set the entities both ways in JPA为什么我需要在 JPA 中同时设置实体
【发布时间】:2016-09-28 18:45:38
【问题描述】:

我有以下两个实体:

@Entity
public class Pilot implements Serializable {
....
    @ManyToOne
    @JoinColumn(name = "FLIGHT_ID")
    private Flight flight;
}

@Entity
public class Flight implements Serializable {
....
    @OneToMany(mappedBy = "flight")
    private List<Pilot> pilots;
}

我正在使用 EJB 将飞行员添加到航班中:

public void addPilotToFlight(String pilotId, String flightId) {
    <code to find Flight f>
    <code to find Pilot p>
    p.setFlight(f);
    f.getPilots().add(p); // Why do I need this one?
}

我的困惑是为什么我需要双向链接对象?

我已经尝试了带有和不带有 f.getPilots().add(p); 部分的代码,在 DB 中它看起来完全一样。但是,当我尝试将f.getPilots(); 用于同一个航班实体对象时,它只会显示我是否完成了上述双向链接。任何人都可以对此有所了解吗?我将不胜感激。提前致谢。

【问题讨论】:

    标签: jpa ejb eclipselink


    【解决方案1】:

    您的问题似乎旨在询问为什么您必须保持双向关系的双方,这是一个常见的问题和混淆的根源。

    CMP 2.0 试图在幕后执行关系维护和魔术,但开销和缺乏控制是一个问题 (IMO),它没有包含在 JPA 中。相反,JPA 实体应该是普通的旧 java 对象。这意味着,如果您希望对关系的一侧所做的更改反映在另一侧,您必须自己进行。

    令人困惑的是,如果您修改关系的一侧而不是另一侧,有时数据库会正确更新,有时不会,有时双方都会显示更改。这完全取决于您更改的哪一侧,以及如何从数据库缓存和刷新实体。对拥有方的更改会持久保存到数据库中,并且 JPA 允许缓存,因此非拥有方在从数据库刷新之前可能不会反映这些更改。

    最佳做法是,如果您希望对象模型与数据库保持同步,则应用程序应对另一侧所做的任何更改都应由应用程序进行。

    【讨论】:

    • 如果在整个应用程序中处理,缓存可以提高性能和可扩展性,但有其成本和缺点。我不会因为这个问题而将其关闭,因为您可以轻松地在实体的访问器方法中设置另一端。
    【解决方案2】:

    因为在 JPA 中您有“单向”关系的概念。如果您不指定“映射依据”属性,您将无法创建 2 个单向关系(1:N 和 N:1),而不是双向 1:N 关系。

    然后有人可能会问“为什么人们需要两种单向关系”?答案是因为 JPA 是为满足甚至奇怪的遗留数据库而构建的。 :-)

    【讨论】:

    • 我需要知道您如何在实体类中定义 Flight 的 PK 以及您如何访问代码中的实体(您如何创建实体管理器等)以便回答您的​​问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多