diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/BinderHelper.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/BinderHelper.java index 54bf7c220785..5f42db351d8c 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/BinderHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/BinderHelper.java @@ -444,9 +444,16 @@ else if ( columnOwner instanceof Join ) { // which are mapped to that column. (There might be multiple such // properties for each column.) if ( columnOwner instanceof PersistentClass ) { - PersistentClass persistentClass = (PersistentClass) columnOwner; + final PersistentClass persistentClass = (PersistentClass) columnOwner; + // Process ToOne associations after Components, Basic and Id properties + final List toOneProperties = new ArrayList<>(); for ( Property property : persistentClass.getProperties() ) { - matchColumnsByProperty( property, columnsToProperty ); + if ( property.getValue() instanceof ToOne ) { + toOneProperties.add( property ); + } + else { + matchColumnsByProperty( property, columnsToProperty ); + } } if ( persistentClass.hasIdentifierProperty() ) { matchColumnsByProperty( persistentClass.getIdentifierProperty(), columnsToProperty ); @@ -458,6 +465,9 @@ else if ( columnOwner instanceof Join ) { matchColumnsByProperty( p, columnsToProperty ); } } + for ( Property property : toOneProperties ) { + matchColumnsByProperty( property, columnsToProperty ); + } } else { for ( Property property : ((Join) columnOwner).getProperties() ) { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/onetoone/JoinColumnTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/onetoone/JoinColumnTest.java new file mode 100644 index 000000000000..b83a31a9fe1a --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/onetoone/JoinColumnTest.java @@ -0,0 +1,99 @@ +package org.hibernate.orm.test.annotations.onetoone; + +import java.io.Serializable; + +import org.hibernate.testing.junit4.BaseUnitTestCase; +import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; +import org.hibernate.testing.orm.junit.JiraKey; +import org.hibernate.testing.orm.junit.Jpa; +import org.junit.jupiter.api.Test; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.persistence.EmbeddedId; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; + +@JiraKey("HHH-17420") +@Jpa( + annotatedClasses = { + JoinColumnTest.LeftEntity.class, + JoinColumnTest.MidEntity.class, + JoinColumnTest.RightEntity.class, + } +) +class JoinColumnTest extends BaseUnitTestCase { + + @Test + void testLeftToRight(EntityManagerFactoryScope scope) { + scope.inTransaction( + entityManager -> { + } + ); + } + + @Entity(name = "LeftEntity") + static class LeftEntity { + + @Embeddable + static class Pk implements Serializable { + @Column + String id_one_2; + + @Column + String id_two_2; + + @Column + String id_three_2; + } + + @EmbeddedId + Pk id; + + @OneToOne(mappedBy = "aLeftEntity") + MidEntity midEntity; + } + + @Entity(name = "MidEntity") + static class MidEntity { + + @Id + @Column + String id; + + @Column + String id_one; + + @Column + String id_two; + + @Column + String id_three; + + @OneToOne + @JoinColumn(name = "id_one", referencedColumnName = "id_one_2", insertable = false, updatable = false) + @JoinColumn(name = "id_two", referencedColumnName = "id_two_2", insertable = false, updatable = false) + @JoinColumn(name = "id_three", referencedColumnName = "id_three_2", insertable = false, updatable = false) + LeftEntity aLeftEntity; + + @OneToOne(mappedBy = "midEntity") + RightEntity rightEntity; + } + + @Entity(name = "RightEntity") + static class RightEntity { + + @Id + Long id; + + @Column + String id_three; + + @OneToOne + @JoinColumn(name = "id_one", referencedColumnName = "id_one", insertable = false, updatable = false) + @JoinColumn(name = "id_two", referencedColumnName = "id_two", insertable = false, updatable = false) + MidEntity midEntity; + } +}