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

View File

@ -21,7 +21,6 @@ import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.IndexedConsumer;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Component;
@ -1791,18 +1790,23 @@ public class ToOneAttributeMapping
lazyTableGroup.setTableGroupInitializerCallback(
tableGroup -> {
join.applyPredicate(
foreignKeyDescriptor.generateJoinPredicate(
sideNature == ForeignKeyDescriptor.Nature.TARGET ?
lhsTableReference :
tableGroup.getPrimaryTableReference(),
sideNature == ForeignKeyDescriptor.Nature.TARGET ?
tableGroup.getPrimaryTableReference() :
lhsTableReference,
sqlExpressionResolver,
creationContext
)
);
final TableReference targetTableReference;
final TableReference keyTableReference;
if ( sideNature == ForeignKeyDescriptor.Nature.TARGET ) {
targetTableReference = lhsTableReference;
keyTableReference = tableGroup.resolveTableReference( foreignKeyDescriptor.getKeyTable() );
}
else {
targetTableReference = tableGroup.resolveTableReference( foreignKeyDescriptor.getTargetTable() );
keyTableReference = lhsTableReference;
}
join.applyPredicate( foreignKeyDescriptor.generateJoinPredicate(
targetTableReference,
keyTableReference,
sqlExpressionResolver,
creationContext
) );
if ( hasNotFoundAction() ) {
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.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")
@SessionFactory
@DomainModel(annotatedClasses = {Split.class, Reference.class})
@DomainModel(annotatedClasses = { Split.class, Reference.class })
public class RefToSecondaryTableTest {
@Test
public void test(SessionFactoryScope scope) {
Split split = new Split();
split.setCode(123);
split.setDescription("blah");
split.setName("Split");
split.setCode( 123 );
split.setDescription( "blah" );
split.setName( "Split" );
Reference reference = new Reference();
reference.setSplit(split);
scope.inTransaction(session -> {
reference.setSplit( split );
scope.inTransaction( session -> {
session.persist( split );
session.persist( reference );
} );
@ -31,7 +31,7 @@ public class RefToSecondaryTableTest {
.getSingleResult();
Assertions.assertEquals( split.getId(), ref.getSplit().getId() );
} );
scope.inSession(session -> {
scope.inSession( session -> {
Reference ref = session.find( Reference.class, reference.getId() );
Assertions.assertEquals( split.getId(), ref.getSplit().getId() );
} );