【问题标题】:Unidirectional one-to-many mapping in Hibernate generates redundant updatesHibernate 中的单向一对多映射会产生冗余更新
【发布时间】:2015-09-02 19:55:57
【问题描述】:

我定义了两个类,Parent 和 Child。父级可以有一个子级列表。

@Entity
public class Parent {
    @Id
    @GeneratedValue(...)
    @SequenceGenerator(...)
    private long id;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "parent_id", referencedColumnName = "id", nullable = false)
    private List<Child> children;

    public Parent() {
        children = new ArrayList<Child>();
    }

    public void addChild(Child child) { children.add(child); }
}

@Entity
public class Child {
    @Id
    @GeneratedValue(...)
    @SequenceGenerator(...)
    private long id;

    // The "Child" table in the db also has a not-null "parent_id" column.
}

如果我将一堆子元素添加到列表中并保持父元素,一切都会按预期工作:Hibernate 获取序列值,存储父元素,然后存储所有子元素。

但是,在完成所有这些操作后,它会更新所有子代,将“parent_id”设置为它在插入时已设置的值!

生成的 SQL 如下所示:

insert into PARENT (id) values (1)
insert into CHILD (parent_id, id) values (1, 1)
insert into CHILD (parent_id, id) values (1, 2)
insert into CHILD (parent_id, id) values (1, 3)
update CHILD set parent_id = 1 WHERE id = 1
update CHILD set parent_id = 1 WHERE id = 2
update CHILD set parent_id = 1 WHERE id = 3

如果我使这个关联是双向的,它可以正常工作,但是我需要在我的子类中引用父类,这是我想要避免的。

存储库是 Spring Data JPA 存储库:

public interface ParentRepository extends PagingAndSortingRepository<Parent, Long> {}

创建和保存对象的(简化)代码:

Parent parent = new Parent();
parent.addChild(new Child());
parent.addChild(new Child());
repo.save(parent);

有什么建议吗?

【问题讨论】:

  • @chsdk,你还需要什么额外的代码?如果有帮助,我将使用 Spring Data JPA 存储库,在该存储库上调用 save(parent)。使用构建器创建后,父母和孩子都是完全不可变的。
  • 尝试将mappedByattribute 添加到您的映射中,如下所示:@OneToMany(mappedBy ="parent", fetch = FetchType.EAGER, cascade = CascadeType.ALL) 其中 parent 应该是 Child 类中 Parent 字段的名称。
  • @chsdk 正如我在问题中提到的,我没有提到我孩子的父母。这是一个单向关联。
  • 啊,我错过了。
  • 没关系 :) 我已经尝试过这个建议,它确实按预期工作。但我不想从我的子对象中引用父对象。

标签: java hibernate jpa


【解决方案1】:

你试过了吗:

@JoinColumn(name = "parent_id", referencedColumnName = "id", nullable = false, insertable=false, updatable=false)

【讨论】:

  • 谢谢,这确实有效!语义有点混乱,但我的理解是您添加这些设置是因为 Child 已经在插入/更新自身(由于级联)并且 Parent 也不需要这样做?
  • 这种方式不会将 FK 插入到表中。如果您希望 FK 的值,您应该将 yes 放入可插入/可更新中。 :)
猜你喜欢
  • 1970-01-01
  • 2011-04-24
  • 1970-01-01
  • 2022-01-03
  • 1970-01-01
  • 2012-06-26
  • 2020-05-03
  • 1970-01-01
  • 2016-06-29
相关资源
最近更新 更多