I have some question about the changed behaviour of the OrderColumn annotation.
First of all, how is this supposed to work in Hibernate 7:
@OneToMany(mappedBy = "foo", cascade = CascadeType.ALL)
@OrderColumn(name = "pos", nullable = false)
private List<Bar> barList;
If pos is not a mapped field in Bar, then “the persistence provider is responsible for maintaining the order upon retrieval and in the database”.
Upon persisting the entity that contains the collection, Hibernate will execute several insert statements but will not include the pos value. If I set nullable = true we see that Hibernate will only update the pos value after the entity has been inserted.
So how is it even possible to use @OrderColumn with a not nullable column?
Second question:
I was told the following is supposedly not a bug. I’d appreciate if someone could help me understand it.
@Entity
public class Foo {
@Id
@GeneratedValue
private Long id;
@OneToMany(mappedBy = "foo", cascade = CascadeType.ALL)
@OrderColumn(name = "pos")
private List<Bar> barList;
public void setBarList(List<Bar> barList) {
barList.forEach(bar -> bar.setFoo(this));
this.barList = barList;
}
}
@Entity
public class Bar {
@Id
@GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "fk_foo")
private Foo foo;
@Column(insertable = false)
private Integer pos;
}
I set insertable = false so that Hibernate 7 will still update the pos column. This works. However, Hibernate will only update the database, but not the entity. Have a look at this test:
Foo foo = new Foo();
foo.setBarList(List.of(new Bar(), new Bar()));
entityManager.persist(foo);
Foo result = entityManager.createQuery("FROM Foo f, IN(f.barList) bar WHERE f.id = 1 AND bar.pos = 0", Foo.class).getSingleResult();
assertNotNull(result.getBarList().getFirst().getId());
// Although something was found, which means 'pos' is not null, the assertion fails.
assertNotNull(result.getBarList().getFirst().getPos());
This demonstrates that Hibernate does indeed update the order column and correctly persists the Bar entities. When loading the entity, the id is set but the order column is null.