From c9a161ebeef8715d899b3e63e17b263fe9a004bd Mon Sep 17 00:00:00 2001 From: Gavin Date: Thu, 11 May 2023 20:38:25 +0200 Subject: [PATCH] allow mappedBy to refer to a non-association property (get rid of a totally unnecessary error) --- .../boot/model/internal/BinderHelper.java | 6 +- .../mappedBy/MappedByNonAssociationTest.java | 70 +++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/mapping/mappedBy/MappedByNonAssociationTest.java 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 80c677bf8e..338077ca8c 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 @@ -1082,9 +1082,13 @@ public class BinderHelper { if ( targetValue instanceof Collection ) { toOne = (ToOne) ( (Collection) targetValue ).getElement(); } - else { + else if ( targetValue instanceof ToOne ) { toOne = (ToOne) targetValue; } + else { + // Nothing to check, EARLY EXIT + return; + } final String referencedEntityName = toOne.getReferencedEntityName(); final PersistentClass referencedClass = persistentClasses.get( referencedEntityName ); PersistentClass ownerClass = propertyHolder.getPersistentClass(); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/mappedBy/MappedByNonAssociationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/mappedBy/MappedByNonAssociationTest.java new file mode 100644 index 0000000000..f078b60bcd --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/mappedBy/MappedByNonAssociationTest.java @@ -0,0 +1,70 @@ +package org.hibernate.orm.test.mapping.mappedBy; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import org.hibernate.Hibernate; +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.Test; + +import java.util.ArrayList; +import java.util.List; + +import static jakarta.persistence.CascadeType.PERSIST; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@SessionFactory +@DomainModel(annotatedClasses = {MappedByNonAssociationTest.Loan.class, MappedByNonAssociationTest.Extensions.class}) +public class MappedByNonAssociationTest { + + @Test void test(SessionFactoryScope scope) { + Extensions ex = new Extensions(); + ex.exExtensionDays = 3L; + ex.exNo = 2L; + ex.exLoanId = 4L; + + Loan loan = new Loan(); + loan.id = 4L; + loan.extensions.add(ex); + + scope.inTransaction(s -> s.persist(loan)); + Loan l1 = scope.fromTransaction(s -> { + Loan ll = s.get(Loan.class, loan.id); + Hibernate.initialize(ll.extensions); + return ll; + }); + assertEquals( 1, l1.extensions.size() ); + assertEquals( loan.id, l1.id ); + assertEquals( ex.exLoanId, l1.extensions.get(0).exLoanId ); + Loan l2 = scope.fromSession(s -> s.createQuery("from Loan join fetch extensions", Loan.class).getSingleResult()); + assertEquals( 1, l2.extensions.size() ); + assertEquals( loan.id, l2.id ); + assertEquals( ex.exLoanId, l2.extensions.get(0).exLoanId ); + } + + @Entity(name="Loan") + static class Loan { + @Id + @Column(name = "LOAN_ID") + private Long id; + + @OneToMany(cascade = PERSIST, mappedBy = "exLoanId") + private List extensions = new ArrayList<>(); + } + + @Entity(name="Extensions") + static class Extensions { + @Id + @Column(name = "EX_LOAN_ID") + private Long exLoanId; + @Id + @Column(name = "EX_NO") + private Long exNo; + @Column(name = "EX_EXTENSION_DAYS") + private Long exExtensionDays; + } + +}