【问题标题】:Which side of bidirectional mapping should be persisted应该保留双向映射的哪一侧
【发布时间】:2020-07-28 21:14:43
【问题描述】:

我在SO和几篇文章上寻找答案,但我认为很遗憾错过了明确的解释,所以我决定问。

假设我们有两个实体(盒子包含几个项目):

@Entity
@Table(name = "box")
class Box
{
    @Id
    private Long id;

    @OneToMany(mappedBy = "box")
    private List<Item> items = new LinkedList<>();
    
    public void addItem(Item item)
    {
        items.add(item);
        item.setBox(this);
    }
    // setters, getters, delete synchronize method
}
@Entity
@Table(name = "item")
class Item
{
    @Id
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "box_id")
    private Box box;

    // setters getters
}

我应该坚持关系的哪一边?

  1. 这是否取决于关系的拥有方?
  2. 它是否取决于级联类型和拥有方没有共同点?
    1. CascadeType.PERSIST 置于Box 实体中,然后将em.persist(box)
    2. CascadeType.PERSIST 放在Item 实体中,然后将em.persist(item)
    3. 两者,persist 由我决定 - 可以是 em.persist(box)em.persist(item)

【问题讨论】:

    标签: java hibernate jpa persistence


    【解决方案1】:

    你可以保持双方的关系。

    如果你持久化盒子实体,你只需要调用实体管理器的persist方法一次并将盒子实体作为参数传递,与项目实体列表一起,盒子项目参数必须具有级联类型.

    如果你持久化item实体,你将不得不调用实体管理器的persist方法N次,其中N是item的数量,传递带有box参数的Item实体,box参数必须有级联类型。在第一个插入 Box 中不会有 ID,但是一旦您插入第一个 Item,Box 就会有 ID,因此在接下来的 N-1 个项目中,您必须使用 Id 建立该 Box,因为如果没有,它将创建 N 个框。

    基于这一切,我认为在大多数逻辑中,最好保留父实体,cob 级联类型保留在表示与子类关系的属性中。

    【讨论】:

    • 感谢@JLazar0 的回答,所以你认为所有权在这里根本不重要吗?
    • 它总是很重要,在这种情况下你可以通过两种方式做到这一点会发生什么,我会选择较少查询会抛出给数据库的一种,因为以一种或另一种方式实现它会假设更多或更少的工作和更好的未来表现。
    猜你喜欢
    • 1970-01-01
    • 2016-03-23
    • 2014-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-19
    • 2020-05-10
    • 2012-07-26
    相关资源
    最近更新 更多