Hello,
we upgraded our maven dependencies and after the migration from hibernate orm 5.3.10 to 5.4.10 our unidirectional relation does not work any more. Here are the entities:
{code:java} import org.hibernate.annotations.Type;
import javax.persistence.*; import java.util.UUID;
@Entity @Table(name = "Parent") public class ParentEntity { @Id @Column(name = "id") @GeneratedValue @Type(type = "org.hibernate.type.UUIDCharType") public UUID id;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "id") public ChildEntity child;
public UUID getId() { return id; }
public void setId(UUID id) { this.id = id; }
public ChildEntity getChild() { return child; }
public void setChild(ChildEntity child) { this.child = child; } } {code}
{code:java} import org.hibernate.annotations.Type;
import javax.persistence.*; import java.util.UUID;
@Entity @Table(name = "Child") public class ChildEntity { @Id @Column(name = "id") @Type(type = "org.hibernate.type.UUIDCharType") public UUID id;
public UUID getId() { return id; }
public void setId(UUID id) { this.id = id; } } {code}
As you can see we have only the relation from ParentEntity to ChildEntity with @OneToOne annotation.
When I create the parent entity and the child entity everything is ok so far. When I delete the parent entity I expect that the child will be deleted first and the parent afterwards. In 5.3.10 I have this order but in 5.4.10 the order is the other way (the parent will be deleted first and the child afterwards).
{code:java} public class App {
public static void main(String[] args) { ParentEntity parent = new ParentEntity();
Transaction transaction = null; try (Session session = HibernateUtil.getSessionFactory().openSession()) { transaction = session.beginTransaction(); session.save(parent); ChildEntity child = new ChildEntity(); child.setId(parent.getId()); session.save(child);
parent.setChild(child); session.update(parent);
transaction.commit(); } catch (Exception e) { e.printStackTrace(); if (transaction != null) { transaction.rollback(); } }
try (Session session = HibernateUtil.getSessionFactory().openSession()) { transaction = session.beginTransaction(); session.delete(parent); transaction.commit(); } catch (Exception e) { e.printStackTrace(); if (transaction != null) { transaction.rollback(); } } } } {code}
The sql log in 5.3.10 is the following:
!image-2020-01-30-15-49-43-223.png| thumbnail width=200,height=183 !
The sql log in 5.4.10 is the following:
!image-2020-01-30-15-50-21-707.png| thumbnail width=200,height=183 !
As you can see the delete order has changed.
As far as I have seen it has something to do with the following ticket [ https://hibernate.atlassian.net/browse/HHH-12436 |https://hibernate.atlassian.net/browse/HHH-12436] and the changes in the hibernate class org.hibernate.cfg.OneToOneSecondPass#doSecondPass.
There is the following code:
{code:java} final ForeignKeyDirection foreignKeyDirection = !BinderHelper.isEmptyAnnotationValue( mappedBy ) ? ForeignKeyDirection.TO_PARENT : ForeignKeyDirection.FROM_PARENT; value.setForeignKeyType(foreignKeyDirection); {code}
hibernate will set the foreignKeyDirection to FROM_PARENT in case mappedBy is not set (which is the case see above).
In hibernate 5.3.10 the following if statement returned true and in 5.4.10 this returns false:
{code:java} org.hibernate.engine.internal.Cascade#cascadeProperty if ( cascadeAssociationNow( cascadePoint, associationType ) ) {code}
I assume the above if statement is not the bug but in this line the bug will have it’s impact.
Here is a simple example: [https://gitlab.com/jmatussek/hibernate-issue-unidirectional-onetoone|https://gitlab.com/jmatussek/hibernate-issue-unidirectional-onetoone]
To reproduce my issue just change the hibernate version in pom.xml.
To me it looks like a bug cause the behavior is different. In case I am wrong could you tell me how to create a unidirectional relation correctly?
Regards
Jan |
|