HHH-16166 Change subtype property access and deprecate unused method in PersistentClass

This commit is contained in:
Marco Belladelli 2023-02-22 14:59:27 +01:00 committed by Christian Beikov
parent 06490876d6
commit d6b5357c7b
3 changed files with 185 additions and 64 deletions

View File

@ -10,6 +10,7 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.Function; import java.util.function.Function;
import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.naming.Identifier;
@ -18,6 +19,7 @@ import org.hibernate.boot.model.relational.QualifiedNameParser;
import org.hibernate.boot.model.relational.QualifiedTableName; import org.hibernate.boot.model.relational.QualifiedTableName;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.Size; import org.hibernate.engine.jdbc.Size;
import org.hibernate.generator.Generator;
import org.hibernate.id.OptimizableGenerator; import org.hibernate.id.OptimizableGenerator;
import org.hibernate.id.enhanced.Optimizer; import org.hibernate.id.enhanced.Optimizer;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;
@ -27,23 +29,25 @@ import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Column; import org.hibernate.mapping.Column;
import org.hibernate.mapping.Contributable; import org.hibernate.mapping.Contributable;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Selectable; import org.hibernate.mapping.Selectable;
import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Value;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.SingleTableEntityPersister; import org.hibernate.persister.entity.SingleTableEntityPersister;
import org.hibernate.generator.Generator;
import org.hibernate.type.BasicType; import org.hibernate.type.BasicType;
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.type.spi.TypeConfiguration;
import static org.hibernate.boot.model.internal.BinderHelper.findPropertyByName;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
* @author Christian Beikov * @author Christian Beikov
@ -198,14 +202,10 @@ public class TemporaryTable implements Exportable, Contributable {
); );
} }
entityDescriptor.visitSubTypeAttributeMappings( visitPluralAttributes( entityDescriptor, (pluralAttribute, attributeName) -> {
attribute -> {
if ( attribute instanceof PluralAttributeMapping ) {
final PluralAttributeMapping pluralAttribute = (PluralAttributeMapping) attribute;
if ( pluralAttribute.getSeparateCollectionTable() != null ) { if ( pluralAttribute.getSeparateCollectionTable() != null ) {
// Ensure that the FK target columns are available // Ensure that the FK target columns are available
ForeignKeyDescriptor keyDescriptor = pluralAttribute.getKeyDescriptor(); final ForeignKeyDescriptor keyDescriptor = pluralAttribute.getKeyDescriptor();
if ( keyDescriptor == null ) { if ( keyDescriptor == null ) {
// This is expected to happen when processing a // This is expected to happen when processing a
// PostInitCallbackEntry because the callbacks // PostInitCallbackEntry because the callbacks
@ -216,10 +216,11 @@ public class TemporaryTable implements Exportable, Contributable {
} }
final ModelPart fkTarget = keyDescriptor.getTargetPart(); final ModelPart fkTarget = keyDescriptor.getTargetPart();
if ( !fkTarget.isEntityIdentifierMapping() ) { if ( !fkTarget.isEntityIdentifierMapping() ) {
final Value value = entityBinding.getSubclassProperty( pluralAttribute.getAttributeName() ) final PersistentClass declaringClass = runtimeModelCreationContext.getBootModel()
.getValue(); .getEntityBinding( pluralAttribute.findContainingEntityMapping().getEntityName() );
final Iterator<Selectable> columnIterator = final Property property = findPropertyByName( declaringClass, attributeName );
( (Collection) value ).getKey().getColumnIterator(); assert property != null;
final Iterator<Selectable> columnIterator = ( (Collection) property.getValue() ).getKey().getColumnIterator();
fkTarget.forEachSelectable( fkTarget.forEachSelectable(
(columnIndex, selection) -> { (columnIndex, selection) -> {
final Selectable selectable = columnIterator.next(); final Selectable selectable = columnIterator.next();
@ -245,11 +246,51 @@ public class TemporaryTable implements Exportable, Contributable {
); );
} }
} }
} );
return columns;
}
);
}
private static void visitPluralAttributes(
EntityMappingType entityDescriptor,
BiConsumer<PluralAttributeMapping, String> consumer) {
entityDescriptor.visitSubTypeAttributeMappings(
attribute -> {
if ( attribute instanceof PluralAttributeMapping ) {
consumer.accept( (PluralAttributeMapping) attribute, attribute.getAttributeName() );
}
else if ( attribute instanceof EmbeddedAttributeMapping ) {
visitPluralAttributes(
(EmbeddedAttributeMapping) attribute,
attribute.getAttributeName(),
consumer
);
} }
} }
); );
return columns;
} }
private static void visitPluralAttributes(
EmbeddedAttributeMapping attributeMapping,
String attributeName,
BiConsumer<PluralAttributeMapping, String> consumer) {
attributeMapping.visitSubParts(
modelPart -> {
if ( modelPart instanceof PluralAttributeMapping ) {
final PluralAttributeMapping pluralAttribute = (PluralAttributeMapping) modelPart;
consumer.accept( pluralAttribute, attributeName + "." + pluralAttribute.getAttributeName() );
}
else if ( modelPart instanceof EmbeddedAttributeMapping ) {
final EmbeddedAttributeMapping embeddedAttribute = (EmbeddedAttributeMapping) modelPart;
visitPluralAttributes(
embeddedAttribute,
attributeName + "." + embeddedAttribute.getAttributeName(),
consumer
);
}
},
null
); );
} }
@ -356,8 +397,9 @@ public class TemporaryTable implements Exportable, Contributable {
entityDescriptor.visitSubTypeAttributeMappings( entityDescriptor.visitSubTypeAttributeMappings(
attribute -> { attribute -> {
if ( !( attribute instanceof PluralAttributeMapping ) ) { if ( !( attribute instanceof PluralAttributeMapping ) ) {
final SimpleValue value = (SimpleValue) entityBinding.getSubclassProperty( attribute.getAttributeName() ) final PersistentClass declaringClass = runtimeModelCreationContext.getBootModel()
.getValue(); .getEntityBinding( attribute.findContainingEntityMapping().getEntityName() );
final SimpleValue value = (SimpleValue) declaringClass.getProperty( attribute.getAttributeName() ).getValue();
final Iterator<Selectable> columnIterator = value.getConstraintColumnIterator(); final Iterator<Selectable> columnIterator = value.getConstraintColumnIterator();
attribute.forEachSelectable( attribute.forEachSelectable(
(columnIndex, selection) -> { (columnIndex, selection) -> {

View File

@ -644,6 +644,7 @@ public abstract class PersistentClass implements IdentifiableTypeClass, Attribut
} }
} }
@Deprecated(since = "6.2")
public Property getSubclassProperty(String propertyName) throws MappingException { public Property getSubclassProperty(String propertyName) throws MappingException {
final Property identifierProperty = getIdentifierProperty(); final Property identifierProperty = getIdentifierProperty();
if ( identifierProperty != null if ( identifierProperty != null

View File

@ -17,11 +17,15 @@ import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Embeddable;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.Inheritance; import jakarta.persistence.Inheritance;
import jakarta.persistence.InheritanceType; import jakarta.persistence.InheritanceType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany; import jakarta.persistence.OneToMany;
import jakarta.persistence.Table; import jakarta.persistence.Table;
@ -34,8 +38,9 @@ import static org.assertj.core.api.Assertions.assertThat;
@DomainModel( annotatedClasses = { @DomainModel( annotatedClasses = {
JoinedInheritanceSameAttributeNameTest.BaseObj.class, JoinedInheritanceSameAttributeNameTest.BaseObj.class,
JoinedInheritanceSameAttributeNameTest.Comment.class, JoinedInheritanceSameAttributeNameTest.Comment.class,
JoinedInheritanceSameAttributeNameTest.Author.class,
JoinedInheritanceSameAttributeNameTest.Post.class, JoinedInheritanceSameAttributeNameTest.Post.class,
JoinedInheritanceSameAttributeNameTest.Author.class JoinedInheritanceSameAttributeNameTest.AuthorEmbedded.class,
} ) } )
@SessionFactory @SessionFactory
@JiraKey( "HHH-16166" ) @JiraKey( "HHH-16166" )
@ -51,6 +56,8 @@ public class JoinedInheritanceSameAttributeNameTest {
session.persist( post ); session.persist( post );
session.persist( comment ); session.persist( comment );
session.persist( author ); session.persist( author );
final AuthorEmbedded authorEmbedded = new AuthorEmbedded( "Andrea", "comments" );
session.persist( authorEmbedded );
} ); } );
} }
@ -161,4 +168,75 @@ public class JoinedInheritanceSameAttributeNameTest {
this.comments = comments; this.comments = comments;
} }
} }
@Embeddable
public static class NestedEmbeddable {
@ElementCollection
@CollectionTable(
name = "author_comments",
joinColumns = @JoinColumn( name = "name", referencedColumnName = "name" )
)
private Set<String> comments;
private Integer testProperty;
public NestedEmbeddable() {
comments = new HashSet<>();
}
public Set<String> getComments() {
return comments;
}
public void setComments(Set<String> comments) {
this.comments = comments;
}
public Integer getTestProperty() {
return testProperty;
}
public void setTestProperty(Integer testProperty) {
this.testProperty = testProperty;
}
}
@Embeddable
public static class AuthorEmbeddable {
private NestedEmbeddable nestedEmbeddable;
public AuthorEmbeddable() {
this.nestedEmbeddable = new NestedEmbeddable();
}
public NestedEmbeddable getNestedEmbeddable() {
return nestedEmbeddable;
}
public void setNestedEmbeddable(NestedEmbeddable nestedEmbeddable) {
this.nestedEmbeddable = nestedEmbeddable;
}
}
@Entity( name = "AuthorEmbedded" )
public static class AuthorEmbedded extends BaseObj {
private AuthorEmbeddable authorEmbeddable;
public AuthorEmbedded() {
}
public AuthorEmbedded(String name, String comment) {
setName( name );
this.authorEmbeddable = new AuthorEmbeddable();
this.authorEmbeddable.getNestedEmbeddable().getComments().add( comment );
}
public AuthorEmbeddable getAuthorEmbeddable() {
return authorEmbeddable;
}
public void setAuthorEmbeddable(AuthorEmbeddable authorEmbeddable) {
this.authorEmbeddable = authorEmbeddable;
}
}
} }