I came across this strange bug while implementing lazy loading using Bytecode enhancement in our application. At some point in our code, we do the following operations in a single session:
SubItem subItem = new SubItem();
subItem.setName("X");
subItem.setId(1L);
em.persist(subItem);
em.flush();
em.detach(subItem);
SubItem output = em.merge(subItem);
em.flush();
(obviously very simplified) With relevant Entities: >>Item.java
@Entity
@Table(name="ITEM")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "TYPE")
public class Item
{
@Column
private String name;
@Id
private Long id;
@OneToMany(mappedBy = "upperItem", cascade = { CascadeType.ALL }, orphanRemoval = true)
private Set<Association> lowerAssociation = new HashSet<>();
}
>>SubItem.java
@Entity
@DiscriminatorValue("subitem")
public class SubItem extends Item {
@Id
private Long id;
@OneToMany(mappedBy = "lowerItem", cascade = { CascadeType.ALL }, orphanRemoval = true)
private Set<Association> superAssociation = new HashSet<>();
}
>>Association.java
@Entity
@Table(name="ASSOCIATION")
public class Association {
@Id
private Long id;
@ManyToOne
@JoinColumn(name = "LOWER_ITEM_ID")
private Item lowerItem;
@ManyToOne
@JoinColumn(name = "UPPER_ITEM_ID")
private Item upperItem;
}
The Code works fine with bytecode enhancement in Version 5.2.12. In higher Versions of Hibernate the code fails on the second flush with an Exception: org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: hibernate.model.SubItem.superAssociation If we turn off bytecode enhancement, it works fine in all the versions I have tried. See the attached Test Case for the concrete example. |