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
This commit is contained in:
parent
82e42ef946
commit
0253e1fe7a
|
@ -241,36 +241,32 @@ public class OneToOneSecondPass implements SecondPass {
|
|||
// 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 <code>Join</code> instance for the mapped by side of a <i>OneToOne</i> association using
|
||||
* a join table.
|
||||
* <p>
|
||||
* Note:<br/>
|
||||
* <ul>
|
||||
* <li>From the mappedBy side we should not create the PK nor the FK, this is handled from the other side.</li>
|
||||
* <li>This method is a dirty dupe of EntityBinder.bindSecondaryTable</li>.
|
||||
* </ul>
|
||||
* </p>
|
||||
* 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();
|
||||
|
|
|
@ -179,7 +179,7 @@ public class ToOneBinder {
|
|||
final FkSecondPass secondPass = new ToOneFkSecondPass(
|
||||
value,
|
||||
joinColumns,
|
||||
!optional && unique, //cannot have nullable and unique on certain DBs like Derby
|
||||
unique,
|
||||
propertyHolder.getPersistentClass(),
|
||||
fullPath,
|
||||
context
|
||||
|
|
|
@ -61,15 +61,13 @@ public class MappedByEmbeddableTest extends BaseCoreFunctionalTestCase {
|
|||
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 -> {
|
||||
|
|
|
@ -16,9 +16,7 @@ import org.hibernate.testing.TestForIssue;
|
|||
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 class SingleTableInheritancePersistTest {
|
|||
|
||||
private String favouriteToy;
|
||||
|
||||
@OneToOne
|
||||
@ManyToOne
|
||||
private Woman mother;
|
||||
|
||||
@OneToOne
|
||||
@ManyToOne
|
||||
private Man father;
|
||||
|
||||
public Child() {
|
||||
|
|
|
@ -206,10 +206,10 @@ public class TablePerClassInheritancePersistTest {
|
|||
|
||||
private String favouriteToy;
|
||||
|
||||
@OneToOne
|
||||
@ManyToOne
|
||||
private Woman mother;
|
||||
|
||||
@OneToOne
|
||||
@ManyToOne
|
||||
private Man father;
|
||||
|
||||
public Child() {
|
||||
|
|
|
@ -16,6 +16,7 @@ import jakarta.persistence.Entity;
|
|||
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 class TablePerClassInheritanceTest {
|
|||
|
||||
private String favouriteToy;
|
||||
|
||||
@OneToOne
|
||||
@ManyToOne
|
||||
private Woman mother;
|
||||
|
||||
@OneToOne
|
||||
@ManyToOne
|
||||
private Man father;
|
||||
|
||||
public Child() {
|
||||
|
|
|
@ -77,12 +77,9 @@ public class InsertOrderingSelfReferenceSingleTableInheritance {
|
|||
@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 class InsertOrderingSelfReferenceSingleTableInheritance {
|
|||
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 class InsertOrderingSelfReferenceSingleTableInheritance {
|
|||
this.longValue = longValue;
|
||||
}
|
||||
|
||||
public NodeLongValue(Long longValue) {
|
||||
super();
|
||||
this.longValue = longValue;
|
||||
}
|
||||
|
||||
public NodeLongValue() {
|
||||
super();
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public class NullablePrimaryKeyTest {
|
|||
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 ) );
|
||||
|
|
|
@ -120,7 +120,7 @@ public class ToOneOnDeleteTest {
|
|||
|
||||
private String name;
|
||||
|
||||
@OneToOne
|
||||
@ManyToOne
|
||||
@OnDelete(action = OnDeleteAction.CASCADE)
|
||||
private Child parent;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ import jakarta.persistence.Id;
|
|||
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 class InheritanceAssociationToOneInnerJoinTest extends BaseEnversJPAFunct
|
|||
public static class EntityA {
|
||||
@Id
|
||||
private Integer id;
|
||||
@OneToOne
|
||||
@ManyToOne
|
||||
private EntityD relationToD;
|
||||
@ManyToOne
|
||||
private EntityC relationToC;
|
||||
|
|
|
@ -8,7 +8,7 @@ package org.hibernate.orm.test.envers.integration.onetoone.bidirectional;
|
|||
|
||||
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() {
|
||||
|
|
|
@ -8,7 +8,7 @@ package org.hibernate.orm.test.envers.integration.onetoone.unidirectional;
|
|||
|
||||
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() {
|
||||
|
|
Loading…
Reference in New Issue