【问题标题】:@OrderColumn in Hibernate/JPA results in redundant UPDATE SQL statementHibernate/JPA 中的 @OrderColumn 导致冗余 UPDATE SQL 语句
【发布时间】:2018-12-12 22:00:51
【问题描述】:

我有一个简单的双向父/子关系,其中子项位于有序列表中。

父母:

@Entity
@Table(name = "Parent")
public class Parent {
    @Id
    private String name;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @OrderColumn(name = "childIndex")
    private final List<Child> children = new ArrayList<>();

    public void setName(final String name) {
        this.name = name;
    }

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

孩子:

@Entity
@Table(name = "Child")
public class Child {

    @Id
    @GeneratedValue(generator = "hibernate-uuid")
    @GenericGenerator(name = "hibernate-uuid", strategy = "uuid2")
    private String id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parentName")
    private Parent parent;

    Child() {}

    public Child(final Parent parent) {
        this.parent = parent;
    }
}

我像这样添加ParentChild 的实例:

SessionFactory sessionFactory = ...
try (Session session = sessionFactory.openSession()) {
    session.beginTransaction();

    Parent parent = new Parent();
    parent.setName("SomeName");
    Child child = new Child(parent);
    parent.addChild(child);

    session.merge(parent);

    session.getTransaction()
            .commit();
}

这可以正常工作并产生以下 SQL:

Hibernate: select parent0_.name as name1_1_1_, children1_.parentName as parentNa2_0_3_, children1_.id as id1_0_3_, children1_.itemIndex as itemInde3_3_, children1_.id as id1_0_0_, children1_.parentName as parentNa2_0_0_ from Parent parent0_ left outer join Child children1_ on parent0_.name=children1_.parentName where parent0_.name=?
Hibernate: insert into Parent (name) values (?)
Hibernate: insert into Child (parentName, id) values (?, ?)
Hibernate: update Child set itemIndex=? where id=?

是否可以在插入Child 行时删除UPDATE 语句并改为设置childIndex

我尝试在OrderColumn 注释上设置nullable=false,但这导致null value in column "childindex" violates not-null constraint 错误,因为Hibernate 仍然尝试插入Child 列而不设置childindex

提前致谢!

编辑:

根据 Mick 的建议,我向子实体显式添加了 childIndex 属性,如下所示:

@Column(nullable = false)
private int childIndex;

虽然这确实会导致列变为非空,但它不会删除额外的 UPDATE 语句。通过这一更改,Hibernate 似乎在 INSERT 上将 childIndex 设置为 0(无论子节点实际上是什么索引;我已经通过添加更多子节点来测试这一点),然后执行更新以更正索引。我假设 Hibernate 只是使用 Child 对象上的任何值,默认情况下为 0,然后在 INSERT 完成后更新它,即使它恰好是正确的值。

【问题讨论】:

  • 子实体仍然需要定义 childIndex,对吗? JPA 还不知道此列,尽管它使用它进行排序。
  • @Mick 现在,JPA 似乎创建了 childIndex 列,即使我没有在 Child 实体上明确定义它。我担心的是 JPA 没有在子实体的初始 INSERT 语句中设置此列的值,而是在单独的 UPDATE 语句中设置它。将 childIndex 列显式添加到 Child 实体会导致在初始 INSERT 时将值设置为 0(无论实际索引应该是什么),然后更新为正确的值。

标签: hibernate jpa


【解决方案1】:

好的,当您合并父实体时,听起来 Hibernate 在这里做了很多魔术。似乎推断子实体上必须有一个附加属性 - 但这个事实被发现是懒惰的 - 因此你的双重更新。如果您还明确地在子实体上定义了适当的“childIndex”属性怎么办? @Column 注释将是注释您的可空要求的正确位置。这也应该强制 Hibernate 在第一个 UPDATE 语句中立即插入值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-10
    • 2023-02-01
    • 2019-05-12
    • 1970-01-01
    • 2015-06-23
    • 1970-01-01
    • 2018-10-10
    • 1970-01-01
    相关资源
    最近更新 更多