diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java index d9742d19d5..4c6d66fc35 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java @@ -31,6 +31,7 @@ import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.mapping.Selectable; import org.hibernate.mapping.ToOne; +import org.hibernate.mapping.Value; import org.hibernate.metamodel.mapping.AssociationKey; import org.hibernate.metamodel.mapping.CollectionPart; import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart; @@ -236,7 +237,10 @@ public class ToOneAttributeMapping final Iterator propertyClosureIterator = entityBinding.getPropertyClosureIterator(); while ( propertyClosureIterator.hasNext() ) { final Property property = propertyClosureIterator.next(); - if ( property.getValue() instanceof OneToOne && name.equals( ( (OneToOne) property.getValue() ).getMappedByProperty() ) ) { + if ( property.getValue() instanceof OneToOne + && name.equals( ( (OneToOne) property.getValue() ).getMappedByProperty() ) + && ( (OneToOne) property.getValue() ).getReferencedEntityName().equals( + declaringType.getJavaTypeDescriptor().getJavaType().getTypeName() ) ) { bidirectionalAttributeName = property.getName(); break; } @@ -247,7 +251,11 @@ public class ToOneAttributeMapping final Iterator propertyClosureIterator = entityBinding.getPropertyClosureIterator(); while ( propertyClosureIterator.hasNext() ) { final Property property = propertyClosureIterator.next(); - if ( property.getValue() instanceof Collection && name.equals( ( (Collection) property.getValue() ).getMappedByProperty() ) ) { + final Value value = property.getValue(); + if ( value instanceof Collection + && name.equals( ( (Collection) value ).getMappedByProperty() ) + && ( (Collection) value ).getElement().getType().getName() + .equals( declaringType.getJavaTypeDescriptor().getJavaType().getTypeName() ) ) { bidirectionalAttributeName = property.getName(); break; } @@ -1046,6 +1054,7 @@ public class ToOneAttributeMapping final ModelPart bidirectionalModelPart = entityMappingType.findSubPart( bidirectionalAttributeName ); // Add the inverse association key side as well to be able to resolve to a CircularFetch if ( bidirectionalModelPart instanceof ToOneAttributeMapping ) { + assert bidirectionalModelPart.getPartMappingType() == declaringTableGroupProducer; final ToOneAttributeMapping bidirectionalAttribute = (ToOneAttributeMapping) bidirectionalModelPart; final AssociationKey secondKey = bidirectionalAttribute.getForeignKeyDescriptor().getAssociationKey(); if ( creationState.registerVisitedAssociationKey( secondKey ) ) { diff --git a/hibernate-core/src/main/java/org/hibernate/property/access/spi/SetterFieldImpl.java b/hibernate-core/src/main/java/org/hibernate/property/access/spi/SetterFieldImpl.java index bdd33670ae..00a38d1a45 100644 --- a/hibernate-core/src/main/java/org/hibernate/property/access/spi/SetterFieldImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/property/access/spi/SetterFieldImpl.java @@ -15,6 +15,7 @@ import org.hibernate.PropertyAccessException; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.ReflectHelper; import org.hibernate.property.access.internal.AbstractFieldSerialForm; +import org.hibernate.proxy.HibernateProxy; /** * Field-based implementation of Setter @@ -67,15 +68,19 @@ public class SetterFieldImpl implements Setter { ); } else { + final String valueType; + if ( value instanceof HibernateProxy ) { + valueType = ( (HibernateProxy) value ).getHibernateLazyInitializer().getEntityName(); + } + else { + valueType = value.getClass().getTypeName(); + } throw new PropertyAccessException( e, String.format( Locale.ROOT, - "Could not set value [%s (`%s`)] by reflection", - value, - value == null ? "" : value.getClass().getTypeName(), - containerClass == null ? "" : containerClass.getTypeName(), - propertyName + "Could not set value of type [%s]", + valueType ), true, containerClass, diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/DomainResultCreationState.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/DomainResultCreationState.java index e0dc5b7e5d..d60a8ebd15 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/DomainResultCreationState.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/DomainResultCreationState.java @@ -8,7 +8,6 @@ package org.hibernate.sql.results.graph; import java.util.List; -import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.metamodel.mapping.AssociationKey; import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; import org.hibernate.metamodel.mapping.ModelPart; @@ -50,9 +49,7 @@ public interface DomainResultCreationState { * Resolve the ModelPart associated with a given NavigablePath. More specific ModelParts should be preferred - e.g. * the SingularAssociationAttributeMapping rather than just the EntityTypeMapping for the associated type */ - default ModelPart resolveModelPart(NavigablePath navigablePath) { - throw new NotYetImplementedFor6Exception( getClass() ); - } + ModelPart resolveModelPart(NavigablePath navigablePath); /** * Visit fetches for the given parent. diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/loading/LoadContainedInDoubleContainingTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/loading/LoadContainedInDoubleContainingTest.java index 8b961c920c..2cc8fb7a54 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/loading/LoadContainedInDoubleContainingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/loading/LoadContainedInDoubleContainingTest.java @@ -6,8 +6,11 @@ */ package org.hibernate.orm.test.loading; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.Test; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import jakarta.persistence.Entity; import jakarta.persistence.Id; @@ -15,16 +18,19 @@ import jakarta.persistence.OneToOne; import static org.assertj.core.api.Assertions.assertThat; -public class LoadContainedInDoubleContainingTest extends BaseCoreFunctionalTestCase { +@DomainModel( + annotatedClasses = { + LoadContainedInDoubleContainingTest.Containing.class, + LoadContainedInDoubleContainingTest.OtherContained.class, + LoadContainedInDoubleContainingTest.Contained.class + } +) +@SessionFactory +public class LoadContainedInDoubleContainingTest { - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { Containing.class, OtherContained.class, Contained.class }; - } - - @Test - public void test() { - inTransaction( session -> { + @BeforeEach + public void setUp(SessionFactoryScope scope) { + scope.inTransaction( session -> { Containing containing = new Containing( 1, "initial" ); OtherContained otherContained = new OtherContained( 2, "initial" ); containing.setOtherContained( otherContained ); @@ -32,19 +38,20 @@ public class LoadContainedInDoubleContainingTest extends BaseCoreFunctionalTestC session.persist( containing ); session.persist( otherContained ); } ); + } - inTransaction( session -> { - OtherContained entity = session.load( OtherContained.class, 2 ); - String text = entity.getText(); + @Test + public void test(SessionFactoryScope scope) { + scope.inTransaction( session -> { + OtherContained otherContained = session.load( OtherContained.class, 2 ); + String text = otherContained.getText(); assertThat( text ).isEqualTo( "initial" ); } ); } - @Entity(name = Containing.NAME) + @Entity(name = "Containing") public static class Containing { - static final String NAME = "Containing"; - @Id private Integer id; private String text; @@ -69,34 +76,39 @@ public class LoadContainedInDoubleContainingTest extends BaseCoreFunctionalTestC public Integer getId() { return id; } + public void setId(Integer id) { this.id = id; } + public String getText() { return text; } + public void setText(String text) { this.text = text; } + public Contained getContained() { return contained; } + public void setContained(Contained contained) { this.contained = contained; } + public OtherContained getOtherContained() { return otherContained; } + public void setOtherContained(OtherContained otherContained) { this.otherContained = otherContained; } } - @Entity(name = Contained.NAME) + @Entity(name = "Contained") public static class Contained { - static final String NAME = "Contained"; - @Id private Integer id; private String text; @@ -115,28 +127,31 @@ public class LoadContainedInDoubleContainingTest extends BaseCoreFunctionalTestC public Integer getId() { return id; } + public void setId(Integer id) { this.id = id; } + public String getText() { return text; } + public void setText(String text) { this.text = text; } + public Containing getContaining() { return containing; } + public void setContaining(Containing containing) { this.containing = containing; } } - @Entity(name = OtherContained.NAME) + @Entity(name = "OtherContained") public static class OtherContained { - static final String NAME = "OtherContained"; - @Id private Integer id; private String text; @@ -155,18 +170,23 @@ public class LoadContainedInDoubleContainingTest extends BaseCoreFunctionalTestC public Integer getId() { return id; } + public void setId(Integer id) { this.id = id; } + public String getText() { return text; } + public void setText(String text) { this.text = text; } + public Containing getContaining() { return containing; } + public void setContaining(Containing containing) { this.containing = containing; }