Hibernate/JPA中的@OrderColumn导致了多余的UPDATE SQL语句



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

母公司:

@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仍然尝试在不设置childindex的情况下插入Child列。

提前感谢!

编辑:

根据Mick的建议,我明确地为Child实体添加了一个childIndex属性,如下所示:

@Column(nullable = false)
private int childIndex;

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

好吧,当您合并父实体时,听起来Hibernate在这里发挥了相当大的作用。它似乎推断出子实体上必须有一个额外的属性,但这一事实被发现是懒惰的,因此您需要进行双重UPDATE。如果您还在子实体上显式定义了一个适当的"childIndex"属性,该怎么办?@Column注释将是注释可为null的需求的正确位置。此外,这应该会迫使Hibernate在第一个UPDATE语句中立即插入值。

最新更新