HHH-15933 Table reference by name and change referenced property owner

This commit is contained in:
Marco Belladelli 2023-01-18 18:27:54 +01:00 committed by Andrea Boriero
parent a4e2fe57cc
commit 49690bf4ce
3 changed files with 40 additions and 29 deletions

View File

@ -22,8 +22,6 @@ import java.util.StringTokenizer;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Stream; import java.util.stream.Stream;
import jakarta.persistence.Embeddable;
import jakarta.persistence.EmbeddedId;
import org.hibernate.AnnotationException; import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.FetchMode; import org.hibernate.FetchMode;
@ -45,11 +43,13 @@ import org.hibernate.boot.spi.PropertyData;
import org.hibernate.dialect.DatabaseVersion; import org.hibernate.dialect.DatabaseVersion;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.mapping.Any; import org.hibernate.mapping.Any;
import org.hibernate.mapping.AttributeContainer;
import org.hibernate.mapping.BasicValue; import org.hibernate.mapping.BasicValue;
import org.hibernate.mapping.Collection; import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Column; import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
import org.hibernate.mapping.Join; import org.hibernate.mapping.Join;
import org.hibernate.mapping.JoinedSubclass;
import org.hibernate.mapping.MappedSuperclass; import org.hibernate.mapping.MappedSuperclass;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property; import org.hibernate.mapping.Property;
@ -60,6 +60,8 @@ import org.hibernate.mapping.ToOne;
import org.hibernate.mapping.Value; import org.hibernate.mapping.Value;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
import jakarta.persistence.Embeddable;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.FetchType; import jakarta.persistence.FetchType;
import jakarta.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne; import jakarta.persistence.OneToOne;
@ -145,7 +147,7 @@ public class BinderHelper {
// figure out which table has the columns by looking // figure out which table has the columns by looking
// for a PersistentClass or Join in the hierarchy of // for a PersistentClass or Join in the hierarchy of
// the target entity which has the first column // the target entity which has the first column
final Object columnOwner = findReferencedColumnOwner( targetEntity, joinColumns.getJoinColumns().get(0), context ); final AttributeContainer columnOwner = findReferencedColumnOwner( targetEntity, joinColumns.getJoinColumns().get(0), context );
checkColumnInSameTable( joinColumns, targetEntity, associatedEntity, context, columnOwner ); checkColumnInSameTable( joinColumns, targetEntity, associatedEntity, context, columnOwner );
// find all properties mapped to each column // find all properties mapped to each column
final List<Property> properties = findPropertiesByColumns( columnOwner, joinColumns, associatedEntity, context ); final List<Property> properties = findPropertiesByColumns( columnOwner, joinColumns, associatedEntity, context );
@ -224,7 +226,7 @@ public class BinderHelper {
PersistentClass associatedEntity, PersistentClass associatedEntity,
String propertyName, String propertyName,
boolean inverse, boolean inverse,
Object columnOwner, AttributeContainer columnOwner,
List<Property> properties, List<Property> properties,
MetadataBuildingContext context) { MetadataBuildingContext context) {
if ( properties.size() == 1 if ( properties.size() == 1
@ -314,7 +316,7 @@ public class BinderHelper {
*/ */
private static Property makeSyntheticComponentProperty( private static Property makeSyntheticComponentProperty(
PersistentClass ownerEntity, PersistentClass ownerEntity,
Object persistentClassOrJoin, AttributeContainer persistentClassOrJoin,
MetadataBuildingContext context, MetadataBuildingContext context,
String syntheticPropertyName, String syntheticPropertyName,
List<Property> properties) { List<Property> properties) {
@ -334,7 +336,12 @@ public class BinderHelper {
result.setInsertable( false ); result.setInsertable( false );
result.setValue( embeddedComponent ); result.setValue( embeddedComponent );
result.setPropertyAccessorName( "embedded" ); result.setPropertyAccessorName( "embedded" );
if ( ownerEntity instanceof JoinedSubclass ) {
ownerEntity.addProperty( result ); ownerEntity.addProperty( result );
}
else {
persistentClassOrJoin.addProperty( result );
}
embeddedComponent.createUniqueKey(); //make it unique embeddedComponent.createUniqueKey(); //make it unique
return result; return result;
} }
@ -683,7 +690,7 @@ public class BinderHelper {
} }
} }
public static Object findReferencedColumnOwner( public static AttributeContainer findReferencedColumnOwner(
PersistentClass persistentClass, PersistentClass persistentClass,
AnnotatedJoinColumn joinColumn, AnnotatedJoinColumn joinColumn,
MetadataBuildingContext context) { MetadataBuildingContext context) {
@ -696,7 +703,7 @@ public class BinderHelper {
* Find the column owner (ie PersistentClass or Join) of columnName. * Find the column owner (ie PersistentClass or Join) of columnName.
* If columnName is null or empty, persistentClass is returned * If columnName is null or empty, persistentClass is returned
*/ */
public static Object findColumnOwner( public static AttributeContainer findColumnOwner(
PersistentClass persistentClass, PersistentClass persistentClass,
String columnName, String columnName,
MetadataBuildingContext context) { MetadataBuildingContext context) {

View File

@ -21,7 +21,6 @@ import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.IndexedConsumer; import org.hibernate.internal.util.IndexedConsumer;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.mapping.Collection; import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
@ -1791,18 +1790,23 @@ public class ToOneAttributeMapping
lazyTableGroup.setTableGroupInitializerCallback( lazyTableGroup.setTableGroupInitializerCallback(
tableGroup -> { tableGroup -> {
join.applyPredicate( final TableReference targetTableReference;
foreignKeyDescriptor.generateJoinPredicate( final TableReference keyTableReference;
sideNature == ForeignKeyDescriptor.Nature.TARGET ? if ( sideNature == ForeignKeyDescriptor.Nature.TARGET ) {
lhsTableReference : targetTableReference = lhsTableReference;
tableGroup.getPrimaryTableReference(), keyTableReference = tableGroup.resolveTableReference( foreignKeyDescriptor.getKeyTable() );
sideNature == ForeignKeyDescriptor.Nature.TARGET ? }
tableGroup.getPrimaryTableReference() : else {
lhsTableReference, targetTableReference = tableGroup.resolveTableReference( foreignKeyDescriptor.getTargetTable() );
keyTableReference = lhsTableReference;
}
join.applyPredicate( foreignKeyDescriptor.generateJoinPredicate(
targetTableReference,
keyTableReference,
sqlExpressionResolver, sqlExpressionResolver,
creationContext creationContext
) ) );
);
if ( hasNotFoundAction() ) { if ( hasNotFoundAction() ) {
getAssociatedEntityMappingType().applyWhereRestrictions( getAssociatedEntityMappingType().applyWhereRestrictions(

View File

@ -8,20 +8,20 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@Disabled("test produces broken SQL and issue needs to be fixed") //@Disabled("test produces broken SQL and issue needs to be fixed")
@TestForIssue(jiraKey = "HHH-15933") @TestForIssue(jiraKey = "HHH-15933")
@SessionFactory @SessionFactory
@DomainModel(annotatedClasses = {Split.class, Reference.class}) @DomainModel(annotatedClasses = { Split.class, Reference.class })
public class RefToSecondaryTableTest { public class RefToSecondaryTableTest {
@Test @Test
public void test(SessionFactoryScope scope) { public void test(SessionFactoryScope scope) {
Split split = new Split(); Split split = new Split();
split.setCode(123); split.setCode( 123 );
split.setDescription("blah"); split.setDescription( "blah" );
split.setName("Split"); split.setName( "Split" );
Reference reference = new Reference(); Reference reference = new Reference();
reference.setSplit(split); reference.setSplit( split );
scope.inTransaction(session -> { scope.inTransaction( session -> {
session.persist( split ); session.persist( split );
session.persist( reference ); session.persist( reference );
} ); } );
@ -31,7 +31,7 @@ public class RefToSecondaryTableTest {
.getSingleResult(); .getSingleResult();
Assertions.assertEquals( split.getId(), ref.getSplit().getId() ); Assertions.assertEquals( split.getId(), ref.getSplit().getId() );
} ); } );
scope.inSession(session -> { scope.inSession( session -> {
Reference ref = session.find( Reference.class, reference.getId() ); Reference ref = session.find( Reference.class, reference.getId() );
Assertions.assertEquals( split.getId(), ref.getSplit().getId() ); Assertions.assertEquals( split.getId(), ref.getSplit().getId() );
} ); } );