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:
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;
}
}
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;
}
}
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).
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();
}
}
}
}
The sql log in 5.3.10 is the following: The sql log in 5.4.10 is the following: 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 and the changes in the hibernate class org.hibernate.cfg.OneToOneSecondPass#doSecondPass. There is the following code:
final ForeignKeyDirection foreignKeyDirection = !BinderHelper.isEmptyAnnotationValue( mappedBy )
? ForeignKeyDirection.TO_PARENT
: ForeignKeyDirection.FROM_PARENT;
value.setForeignKeyType(foreignKeyDirection);
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:
org.hibernate.engine.internal.Cascade#cascadeProperty
if ( cascadeAssociationNow( cascadePoint, associationType ) )
Here is a simple example: 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 |