From 0253e1fe7a7cc4eb64fcc48f07630dee8d4fc20a Mon Sep 17 00:00:00 2001 From: Gavin Date: Sat, 26 Nov 2022 14:43:26 +0100 Subject: [PATCH] HHH-15767 put unique constraints where they belong on optional @OneToOne associations this was a bug that allowed people to use @OneToOne as a regular @ManyToOne and ... people did ... as evidenced by all these bogus tests I just fixed this is in principle a breaking change because it breaks code that was broken --- .../org/hibernate/cfg/OneToOneSecondPass.java | 44 +++++++++---------- .../java/org/hibernate/cfg/ToOneBinder.java | 2 +- .../embeddable/MappedByEmbeddableTest.java | 8 ++-- .../SingleTableInheritancePersistTest.java | 6 +-- .../TablePerClassInheritancePersistTest.java | 4 +- .../TablePerClassInheritanceTest.java | 5 ++- ...ngSelfReferenceSingleTableInheritance.java | 17 ++++--- .../primarykey/NullablePrimaryKeyTest.java | 2 +- .../ondelete/toone/ToOneOnDeleteTest.java | 2 +- ...eritanceAssociationToOneInnerJoinTest.java | 3 +- .../bidirectional/BiRefIngEntity.java | 4 +- .../unidirectional/UniRefIngEntity.java | 4 +- 12 files changed, 48 insertions(+), 53 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java b/hibernate-core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java index 80e71606de..a0b5c2fbb8 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java @@ -241,36 +241,32 @@ private void bindUnowned(Map persistentClasses, OneToOn // if not, then we need to create a many to one and formula // but actually, since entities linked by a one to one need // to share the same composite id class, this cannot happen - boolean rightOrder = true; - - if ( rightOrder ) { - final ToOneFkSecondPass secondPass = new ToOneFkSecondPass( - oneToOne, - joinColumns, - !optional, //cannot have nullable and unique on certain DBs - propertyHolder.getPersistentClass(), - qualify( propertyHolder.getPath(), propertyName), - buildingContext - ); - secondPass.doSecondPass(persistentClasses); - //no column associated since it's a one to one - propertyHolder.addProperty( property, inferredData.getDeclaringClass() ); - } +// boolean rightOrder = true; +// +// if ( rightOrder ) { + final ToOneFkSecondPass secondPass = new ToOneFkSecondPass( + oneToOne, + joinColumns, + true, + propertyHolder.getPersistentClass(), + qualify( propertyHolder.getPath(), propertyName), + buildingContext + ); + secondPass.doSecondPass(persistentClasses); + //no column associated since it's a one to one + propertyHolder.addProperty( property, inferredData.getDeclaringClass() ); +// } // else { // this is a @ManyToOne with Formula // } } /** - * Builds the Join instance for the mapped by side of a OneToOne association using - * a join table. - *

- * Note:
- *

- *

+ * Builds the {@link Join} instance for the unowned side + * of a {@code OneToOne} association using a join table. + * From the {@code mappedBy} side we should not create + * neither the PK, nor the FK, this is all handled from + * the owning side. */ private Join buildJoinFromMappedBySide(PersistentClass persistentClass, Property otherSideProperty, Join originalJoin) { Join join = new Join(); diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/ToOneBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/ToOneBinder.java index bb15a4a23e..59f0272d06 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/ToOneBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/ToOneBinder.java @@ -179,7 +179,7 @@ private static void bindManyToOne( final FkSecondPass secondPass = new ToOneFkSecondPass( value, joinColumns, - !optional && unique, //cannot have nullable and unique on certain DBs like Derby + unique, propertyHolder.getPersistentClass(), fullPath, context diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/embeddable/MappedByEmbeddableTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/embeddable/MappedByEmbeddableTest.java index 886481ee04..cf5197617d 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/embeddable/MappedByEmbeddableTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/embeddable/MappedByEmbeddableTest.java @@ -61,15 +61,13 @@ public void smoke() { Contained contained2 = embed2.getContained(); // switch associations: 1:1 2:2 -> 1:2 2:1 + contained1.setContaining( null ); + embed2.setContained( null ); + session.flush(); embed1.setContained( contained2 ); contained2.setContaining( containing1 ); embed2.setContained( contained1 ); contained1.setContaining( containing2 ); - - session.update( containing1 ); - session.update( containing2 ); - session.update( contained1 ); - session.update( contained2 ); } ); inTransaction( session -> { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/discriminator/SingleTableInheritancePersistTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/discriminator/SingleTableInheritancePersistTest.java index b1c8762444..c586a3cdeb 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/discriminator/SingleTableInheritancePersistTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/discriminator/SingleTableInheritancePersistTest.java @@ -16,9 +16,7 @@ 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.AfterEach; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import jakarta.persistence.CascadeType; @@ -225,10 +223,10 @@ public static class Child extends Person { private String favouriteToy; - @OneToOne + @ManyToOne private Woman mother; - @OneToOne + @ManyToOne private Man father; public Child() { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/discriminator/TablePerClassInheritancePersistTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/discriminator/TablePerClassInheritancePersistTest.java index f581defc5a..0edc74b1d6 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/discriminator/TablePerClassInheritancePersistTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/discriminator/TablePerClassInheritancePersistTest.java @@ -206,10 +206,10 @@ public static class Child extends Person { private String favouriteToy; - @OneToOne + @ManyToOne private Woman mother; - @OneToOne + @ManyToOne private Man father; public Child() { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/discriminator/TablePerClassInheritanceTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/discriminator/TablePerClassInheritanceTest.java index 758ee9c4b3..84acba5f3f 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/discriminator/TablePerClassInheritanceTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/discriminator/TablePerClassInheritanceTest.java @@ -16,6 +16,7 @@ import jakarta.persistence.Id; import jakarta.persistence.Inheritance; import jakarta.persistence.InheritanceType; +import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; import jakarta.persistence.OneToOne; @@ -166,10 +167,10 @@ public static class Child extends Person { private String favouriteToy; - @OneToOne + @ManyToOne private Woman mother; - @OneToOne + @ManyToOne private Man father; public Child() { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/insertordering/InsertOrderingSelfReferenceSingleTableInheritance.java b/hibernate-core/src/test/java/org/hibernate/orm/test/insertordering/InsertOrderingSelfReferenceSingleTableInheritance.java index 19626d1671..f21c66e692 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/insertordering/InsertOrderingSelfReferenceSingleTableInheritance.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/insertordering/InsertOrderingSelfReferenceSingleTableInheritance.java @@ -77,12 +77,9 @@ public void test1(EntityManagerFactoryScope scope) { @Test public void test2(EntityManagerFactoryScope scope) { scope.inTransaction( entityManager -> { - NodeLongValue aparam = new NodeLongValue(); - aparam.setLongValue( 123L ); - - ContentNode xa = new ContentNode( aparam, null, null ); - ContentNode xb = new ContentNode( aparam, null, null ); - ContentNode xc = new ContentNode( aparam, xb, null ); + ContentNode xa = new ContentNode(new NodeLongValue(123L), null, null ); + ContentNode xb = new ContentNode(new NodeLongValue(123L), null, null ); + ContentNode xc = new ContentNode(new NodeLongValue(123L), xb, null ); NodeLink nl = new NodeLink( xc ); @@ -118,8 +115,9 @@ public void test4(EntityManagerFactoryScope scope) { NodeStringValue stringVal = new NodeStringValue(); stringVal.setStringValue( "Node 123" ); + ContentNode cn0 = new ContentNode( null, null, null ); ContentNode cn1 = new ContentNode( stringVal, null, null ); - ContentNode cn2 = new ContentNode( longVal, cn1, null ); + ContentNode cn2 = new ContentNode( longVal, cn0, null ); ContentNode cn3 = new ContentNode( null, cn1, cn2 ); @@ -345,6 +343,11 @@ public NodeLongValue(String dataType, Long longValue) { this.longValue = longValue; } + public NodeLongValue(Long longValue) { + super(); + this.longValue = longValue; + } + public NodeLongValue() { super(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/primarykey/NullablePrimaryKeyTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/primarykey/NullablePrimaryKeyTest.java index 8311402977..0ecbf3b08b 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/primarykey/NullablePrimaryKeyTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/primarykey/NullablePrimaryKeyTest.java @@ -54,7 +54,7 @@ public void testGeneratedSql() { metadata, false ); - String expectedMappingTableSql = "create table personAddress (address_id bigint, " + + String expectedMappingTableSql = "create table personAddress (address_id bigint unique, " + "person_id bigint not null, primary key (person_id))"; assertEquals( "Wrong SQL", expectedMappingTableSql, commands.get( 2 ) ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/ondelete/toone/ToOneOnDeleteTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/ondelete/toone/ToOneOnDeleteTest.java index 163d1ddd01..e64fa9dee9 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/ondelete/toone/ToOneOnDeleteTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/ondelete/toone/ToOneOnDeleteTest.java @@ -120,7 +120,7 @@ public static class GrandChild { private String name; - @OneToOne + @ManyToOne @OnDelete(action = OnDeleteAction.CASCADE) private Child parent; } diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/InheritanceAssociationToOneInnerJoinTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/InheritanceAssociationToOneInnerJoinTest.java index 41f79e0b67..d234f5b276 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/InheritanceAssociationToOneInnerJoinTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/InheritanceAssociationToOneInnerJoinTest.java @@ -13,7 +13,6 @@ import jakarta.persistence.Inheritance; import jakarta.persistence.InheritanceType; import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToOne; import jakarta.persistence.criteria.JoinType; import org.hibernate.envers.Audited; @@ -131,7 +130,7 @@ public void testAuditQueryWithJoinedInheritanceSubclassPropertyProjectionWithRel public static class EntityA { @Id private Integer id; - @OneToOne + @ManyToOne private EntityD relationToD; @ManyToOne private EntityC relationToC; diff --git a/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/onetoone/bidirectional/BiRefIngEntity.java b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/onetoone/bidirectional/BiRefIngEntity.java index 68b841f251..8db5e09c02 100644 --- a/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/onetoone/bidirectional/BiRefIngEntity.java +++ b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/onetoone/bidirectional/BiRefIngEntity.java @@ -8,7 +8,7 @@ import jakarta.persistence.Entity; import jakarta.persistence.Id; -import jakarta.persistence.OneToOne; +import jakarta.persistence.ManyToOne; import org.hibernate.envers.Audited; @@ -24,7 +24,7 @@ public class BiRefIngEntity { private String data; @Audited - @OneToOne + @ManyToOne private BiRefEdEntity reference; public BiRefIngEntity() { diff --git a/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/onetoone/unidirectional/UniRefIngEntity.java b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/onetoone/unidirectional/UniRefIngEntity.java index 073ff2e545..3ded2c3516 100644 --- a/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/onetoone/unidirectional/UniRefIngEntity.java +++ b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/onetoone/unidirectional/UniRefIngEntity.java @@ -8,7 +8,7 @@ import jakarta.persistence.Entity; import jakarta.persistence.Id; -import jakarta.persistence.OneToOne; +import jakarta.persistence.ManyToOne; import org.hibernate.envers.Audited; @@ -26,7 +26,7 @@ public class UniRefIngEntity { private String data; @Audited - @OneToOne + @ManyToOne private UniRefEdEntity reference; public UniRefIngEntity() {