Removed ForeignKeyDescriptor direction attribute

This commit is contained in:
Andrea Boriero 2020-04-03 13:38:47 +01:00 committed by Steve Ebersole
parent 7f4c25095e
commit e5a2b582fe
13 changed files with 210 additions and 415 deletions

View File

@ -148,6 +148,7 @@ public class OneToOneSecondPass implements SecondPass {
}
}
else {
value.setMappedByProperty( mappedBy );
PersistentClass otherSide = (PersistentClass) persistentClasses.get( value.getReferencedEntityName() );
Property otherSideProperty;
try {

View File

@ -28,6 +28,7 @@ public class OneToOne extends ToOne {
private KeyValue identifier;
private String propertyName;
private String entityName;
private String mappedByProperty;
public OneToOne(MetadataBuildingContext buildingContext, Table table, PersistentClass owner) throws MappingException {
super( buildingContext, table );
@ -166,5 +167,12 @@ public class OneToOne extends ToOne {
&& Objects.equals( entityName, other.entityName )
&& constrained == other.constrained;
}
public String getMappedByProperty() {
return mappedByProperty;
}
public void setMappedByProperty(String mappedByProperty) {
this.mappedByProperty = mappedByProperty;
}
}

View File

@ -15,7 +15,6 @@ import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.type.ForeignKeyDirection;
/**
* @author Steve Ebersole
@ -23,8 +22,6 @@ import org.hibernate.type.ForeignKeyDirection;
public interface ForeignKeyDescriptor extends VirtualModelPart {
String PART_NAME = "{fk}";
ForeignKeyDirection getDirection();
DomainResult createCollectionFetchDomainResult(
NavigablePath collectionPath,
TableGroup tableGroup,

View File

@ -7,6 +7,7 @@
package org.hibernate.metamodel.mapping.internal;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
import org.hibernate.metamodel.mapping.ManagedMappingType;
import org.hibernate.metamodel.mapping.MappingType;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
@ -45,4 +46,7 @@ public abstract class AbstractAttributeMapping implements AttributeMapping {
public JavaTypeDescriptor getJavaTypeDescriptor() {
return getMappedTypeDescriptor().getMappedJavaTypeDescriptor();
}
void setForeignKeyDescriptor(ForeignKeyDescriptor foreignKeyDescriptor){
}
}

View File

@ -7,6 +7,7 @@
package org.hibernate.metamodel.mapping.internal;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
import org.hibernate.metamodel.mapping.ManagedMappingType;
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;

View File

@ -8,41 +8,25 @@ package org.hibernate.metamodel.mapping.internal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.engine.FetchTiming;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingType;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.query.ComparisonOperator;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.SqlAstJoinType;
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.ast.tree.expression.ColumnReference;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.SqlTuple;
import org.hibernate.sql.ast.tree.from.CompositeTableGroup;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.sql.ast.tree.from.TableReferenceJoin;
import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate;
@ -50,49 +34,34 @@ import org.hibernate.sql.ast.tree.predicate.Junction;
import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableForeignKeyResultImpl;
import org.hibernate.type.ForeignKeyDirection;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Andrea Boriero
*/
public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, EmbeddableValuedFetchable {
public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, ModelPart {
private String name;
private StateArrayContributorMetadataAccess attributeMetadataAccess;
private final String keyColumnContainingTable;
private final List<String> keyColumnExpressions;
private final String targetColumnContainingTable;
private final List<String> targetColumnExpressions;
private final EmbeddableValuedModelPart mappingType;
private final List<JdbcMapping> jdbcMappings;
private final ForeignKeyDirection fKeyDirection;
private final int hasCode;
public EmbeddedForeignKeyDescriptor(
String attributeName,
EmbeddedIdentifierMappingImpl mappingType,
StateArrayContributorMetadataAccess attributeMetadataAccess,
ForeignKeyDirection fKeyDirection,
String keyColumnContainingTable,
List<String> keyColumnExpressions,
String targetColumnContainingTable,
List<String> targetColumnExpressions,
MappingModelCreationProcess creationProcess) {
name = attributeName;
this.attributeMetadataAccess = attributeMetadataAccess;
this.keyColumnContainingTable = keyColumnContainingTable;
this.keyColumnExpressions = keyColumnExpressions;
this.targetColumnContainingTable = targetColumnContainingTable;
this.targetColumnExpressions = targetColumnExpressions;
this.mappingType = mappingType;
this.fKeyDirection = fKeyDirection;
jdbcMappings = new ArrayList<>();
mappingType.getAttributes().forEach(
attribute -> {
@ -122,18 +91,6 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Embed
}
}
);
this.hasCode = Objects.hash(
keyColumnContainingTable,
keyColumnExpressions,
targetColumnContainingTable,
targetColumnExpressions
);
}
@Override
public ForeignKeyDirection getDirection() {
return fKeyDirection;
}
@Override
@ -410,162 +367,4 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Embed
throw new UnsupportedOperationException();
}
@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
EmbeddedForeignKeyDescriptor that = (EmbeddedForeignKeyDescriptor) o;
return keyColumnContainingTable.equals( that.keyColumnContainingTable ) &&
keyColumnExpressions.equals( that.keyColumnExpressions ) &&
targetColumnContainingTable.equals( that.targetColumnContainingTable ) &&
targetColumnExpressions.equals( that.targetColumnExpressions );
}
@Override
public int hashCode() {
return hasCode;
}
@Override
public TableGroupJoin createTableGroupJoin(
NavigablePath navigablePath,
TableGroup lhs,
String explicitSourceAlias,
SqlAstJoinType sqlAstJoinType,
LockMode lockMode,
SqlAliasBaseGenerator aliasBaseGenerator,
SqlExpressionResolver sqlExpressionResolver,
SqlAstCreationContext creationContext) {
final CompositeTableGroup compositeTableGroup = new CompositeTableGroup(
navigablePath,
this,
lhs
);
lhs.addTableGroupJoin( new TableGroupJoin( navigablePath, SqlAstJoinType.INNER, compositeTableGroup, null ) );
return new TableGroupJoin(
navigablePath,
sqlAstJoinType,
compositeTableGroup
);
}
@Override
public EmbeddableMappingType getEmbeddableTypeDescriptor() {
return (EmbeddableMappingType) mappingType;
}
@Override
public String getContainingTableExpression() {
return keyColumnContainingTable;
}
@Override
public List<String> getMappedColumnExpressions() {
return keyColumnExpressions;
}
@Override
public SingularAttributeMapping getParentInjectionAttributeMapping() {
return null;
}
@Override
public Expression toSqlExpression(
TableGroup tableGroup,
Clause clause,
SqmToSqlAstConverter walker,
SqlAstCreationState sqlAstCreationState) {
final List<ColumnReference> columnReferences = CollectionHelper.arrayList( keyColumnExpressions.size() );
final TableReference tableReference = tableGroup.resolveTableReference( getContainingTableExpression() );
getEmbeddableTypeDescriptor().visitJdbcTypes(
new Consumer<JdbcMapping>() {
private int index = 0;
@Override
public void accept(JdbcMapping jdbcMapping) {
final String attrColumnExpr = keyColumnExpressions.get( index++ );
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
tableReference,
attrColumnExpr
),
sqlAstProcessingState -> new ColumnReference(
tableReference.getIdentificationVariable(),
attrColumnExpr,
jdbcMapping,
sqlAstCreationState.getCreationContext().getSessionFactory()
)
);
columnReferences.add( (ColumnReference) columnReference );
}
},
clause,
sqlAstCreationState.getCreationContext().getSessionFactory().getTypeConfiguration()
);
return new SqlTuple( columnReferences, this );
}
@Override
public String getSqlAliasStem() {
return name;
}
@Override
public ModelPart findSubPart(
String name, EntityMappingType treatTargetType) {
return mappingType.findSubPart( name, treatTargetType );
}
@Override
public void visitSubParts(
Consumer<ModelPart> consumer, EntityMappingType treatTargetType) {
mappingType.visitSubParts( consumer, treatTargetType );
}
@Override
public String getFetchableName() {
return name;
}
@Override
public FetchStrategy getMappedFetchStrategy() {
return null;
}
@Override
public Fetch generateFetch(
FetchParent fetchParent,
NavigablePath fetchablePath,
FetchTiming fetchTiming,
boolean selected,
LockMode lockMode,
String resultVariable,
DomainResultCreationState creationState) {
return new EmbeddableFetchImpl(
fetchablePath,
this,
fetchParent,
fetchTiming,
selected,
attributeMetadataAccess.resolveAttributeMetadata( null ).isNullable(),
creationState
);
}
@Override
public int getNumberOfFetchables() {
return getEmbeddableTypeDescriptor().getNumberOfAttributeMappings();
}
}

View File

@ -315,7 +315,7 @@ public class EmbeddedIdentifierMappingImpl implements CompositeIdentifierMapping
getAttributes().forEach(
attribute -> {
if ( attribute instanceof SingularAssociationAttributeMapping ) {
SingularAssociationAttributeMapping associationAttributeMapping = (SingularAssociationAttributeMapping) attribute;
final SingularAssociationAttributeMapping associationAttributeMapping = (SingularAssociationAttributeMapping) attribute;
associationAttributeMapping.getForeignKeyDescriptor().visitReferringColumns( consumer );
}
else {

View File

@ -28,6 +28,7 @@ import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.mapping.BasicValue;
import org.hibernate.mapping.Collection;
@ -54,7 +55,6 @@ import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.ManagedMappingType;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
@ -691,7 +691,7 @@ public class MappingModelCreationHelper {
creationProcess.registerForeignKeyPostInitCallbacks(
() -> {
interpretKeyDescriptor(
interpretPluralAttributeMappingKeyDescriptor(
pluralAttributeMapping,
bootValueMapping,
collectionDescriptor,
@ -706,16 +706,34 @@ public class MappingModelCreationHelper {
return pluralAttributeMapping;
}
private static void interpretKeyDescriptor(
private static void interpretPluralAttributeMappingKeyDescriptor(
PluralAttributeMappingImpl attributeMapping,
Collection bootValueMapping,
CollectionPersister collectionDescriptor,
ManagedMappingType declaringType,
Dialect dialect,
MappingModelCreationProcess creationProcess) {
ModelPart attributeMappingSubPart = null;
if ( !StringHelper.isEmpty( collectionDescriptor.getMappedByProperty() ) ) {
attributeMappingSubPart = attributeMapping.findSubPart( collectionDescriptor.getMappedByProperty(), null );
}
if ( attributeMappingSubPart != null && attributeMappingSubPart instanceof SingularAssociationAttributeMapping ) {
final SingularAssociationAttributeMapping referencedAttributeMapping = (SingularAssociationAttributeMapping) attributeMappingSubPart;
setRefererencedAttributeForeignKeyDescriptor(
attributeMapping,
referencedAttributeMapping,
(EntityPersister) referencedAttributeMapping.getDeclaringType(),
collectionDescriptor.getMappedByProperty(),
dialect,
creationProcess
);
return;
}
final KeyValue bootValueMappingKey = bootValueMapping.getKey();
final Type keyType = bootValueMappingKey.getType();
final ModelPart fkTarget;
final String lhsPropertyName = collectionDescriptor.getCollectionType().getLHSPropertyName();
if ( lhsPropertyName == null ) {
@ -729,10 +747,8 @@ public class MappingModelCreationHelper {
assert bootValueMappingKey.getColumnSpan() == 1;
assert fkTarget instanceof BasicValuedModelPart;
final BasicValuedModelPart simpleFkTarget = (BasicValuedModelPart) fkTarget;
attributeMapping.setForeignKeyDescriptor(
new SimpleForeignKeyDescriptor(
( (AssociationType) bootValueMapping.getType() ).getForeignKeyDirection(),
getTableIdentifierExpression( bootValueMappingKey.getTable(), creationProcess ),
bootValueMappingKey.getColumnIterator().next().getText( dialect ),
simpleFkTarget.getContainingTableExpression(),
@ -742,44 +758,25 @@ public class MappingModelCreationHelper {
);
}
else if ( fkTarget instanceof EmbeddableValuedModelPart ) {
final EmbeddableValuedModelPart embeddedFkTarget = (EmbeddableValuedModelPart) fkTarget;
List<JdbcMapping> jdbcMappings = new ArrayList<>();
embeddedFkTarget.visitJdbcTypes(
jdbcMapping -> {
jdbcMappings.add( jdbcMapping );
},
null,
creationProcess.getCreationContext().getTypeConfiguration()
);
List<String> keyColumnExpressions = new ArrayList<>();
bootValueMapping.getColumnIterator().forEachRemaining( column -> keyColumnExpressions.add( column.getText(
dialect ) ) );
List<String> targetColumnExpressions = new ArrayList<>();
fkTarget.visitColumns(
(table, column, mapping) ->
targetColumnExpressions.add( column ) );
EmbeddedForeignKeyDescriptor embeddedForeignKeyDescriptor = new EmbeddedForeignKeyDescriptor(
attributeMapping.getAttributeName(),
(EmbeddedIdentifierMappingImpl) fkTarget,
getStateArrayContributorMetadataAccess(attributeMapping.getPropertyAccess()),
( (AssociationType) bootValueMapping.getType() ).getForeignKeyDirection(),
getTableIdentifierExpression( bootValueMapping.getTable(), creationProcess ),
keyColumnExpressions,
embeddedFkTarget.getContainingTableExpression(),
targetColumnExpressions,
final EmbeddedForeignKeyDescriptor embeddedForeignKeyDescriptor =
buildEmbeddedForeignKeyDescriptor(
(EmbeddableValuedModelPart) fkTarget,
attributeMapping,
bootValueMapping,
dialect,
creationProcess
);
creationProcess
);
attributeMapping.setForeignKeyDescriptor( embeddedForeignKeyDescriptor );
}else {
}
else {
throw new NotYetImplementedFor6Exception(
"Support for composite foreign-keys not yet implemented: " + bootValueMapping.getRole()
);
}
}
public static void interpretKeyDescriptor(
public static void interpretSingularAssociationAttributeMappingKeyDescriptor(
SingularAssociationAttributeMapping attributeMapping,
Property bootProperty,
ToOne bootValueMapping,
@ -789,11 +786,35 @@ public class MappingModelCreationHelper {
if ( attributeMapping.getForeignKeyDescriptor() != null ) {
return;
}
EntityPersister referencedEntityDescriptor = creationProcess.getEntityPersister(
bootValueMapping.getReferencedEntityName() );
final ModelPart fkTarget;
final ForeignKeyDirection foreignKeyDirection = ( (AssociationType) bootValueMapping.getType() ).getForeignKeyDirection();
referencedEntityDescriptor.prepareMappingModel( creationProcess );
attributeMapping.setForeignKeyDirection( foreignKeyDirection );
attributeMapping.setIdentifyingColumnsTableExpression( bootValueMapping.getTable().getName() );
final EntityPersister referencedEntityDescriptor = creationProcess
.getEntityPersister( bootValueMapping.getReferencedEntityName() );
String referencedPropertyName = bootValueMapping.getReferencedPropertyName();
if ( referencedPropertyName == null && bootValueMapping instanceof OneToOne ) {
referencedPropertyName = ( (OneToOne) bootValueMapping ).getMappedByProperty();
}
if ( referencedPropertyName != null ) {
final SingularAssociationAttributeMapping referencedAttributeMapping =
(SingularAssociationAttributeMapping) referencedEntityDescriptor.findSubPart( referencedPropertyName );
setRefererencedAttributeForeignKeyDescriptor(
attributeMapping,
referencedAttributeMapping,
referencedEntityDescriptor,
referencedPropertyName,
dialect,
creationProcess
);
return;
}
final ModelPart fkTarget;
if ( bootValueMapping.isReferenceToPrimaryKey() ) {
fkTarget = referencedEntityDescriptor.getIdentifierMapping();
}
@ -803,87 +824,35 @@ public class MappingModelCreationHelper {
if ( fkTarget instanceof BasicValuedModelPart ) {
final String keyColumnExpression;
if ( bootValueMapping.isReferenceToPrimaryKey() ) {
final Iterator<Selectable> columnIterator = bootValueMapping.getColumnIterator();
final Table table = bootValueMapping.getTable();
if ( columnIterator.hasNext() ) {
keyColumnExpression = columnIterator.next().getText( dialect );
}
else {
// case of ToOne with @PrimaryKeyJoinColumn
keyColumnExpression = table.getColumn( 0 ).getName();
}
final BasicValuedModelPart simpleFkTarget = (BasicValuedModelPart) fkTarget;
ForeignKeyDescriptor foreignKeyDescriptor = new SimpleForeignKeyDescriptor(
foreignKeyDirection,
getTableIdentifierExpression( table, creationProcess ),
keyColumnExpression,
simpleFkTarget.getContainingTableExpression(),
simpleFkTarget.getMappedColumnExpression(),
simpleFkTarget.getJdbcMapping()
);
attributeMapping.setForeignKeyDescriptor( foreignKeyDescriptor );
final Iterator<Selectable> columnIterator = bootValueMapping.getColumnIterator();
final Table table = bootValueMapping.getTable();
if ( columnIterator.hasNext() ) {
keyColumnExpression = columnIterator.next().getText( dialect );
}
else {
SingularAssociationAttributeMapping subPart = (SingularAssociationAttributeMapping) referencedEntityDescriptor
.findSubPart( bootValueMapping.getReferencedPropertyName() );
ForeignKeyDescriptor foreignKeyDescriptor = subPart.getForeignKeyDescriptor();
if ( foreignKeyDescriptor == null ) {
PersistentClass entityBinding = creationProcess.getCreationContext()
.getBootModel()
.getEntityBinding(
referencedEntityDescriptor.getEntityName() );
Property property = entityBinding.getProperty( bootValueMapping.getReferencedPropertyName() );
interpretKeyDescriptor(
subPart,
property,
(ToOne) property.getValue(),
referencedEntityDescriptor,
dialect,
creationProcess
);
attributeMapping.setForeignKeyDescriptor( subPart.getForeignKeyDescriptor() );
}
else {
attributeMapping.setForeignKeyDescriptor( foreignKeyDescriptor );
}
// case of ToOne with @PrimaryKeyJoinColumn
keyColumnExpression = table.getColumn( 0 ).getName();
}
final BasicValuedModelPart simpleFkTarget = (BasicValuedModelPart) fkTarget;
final ForeignKeyDescriptor foreignKeyDescriptor = new SimpleForeignKeyDescriptor(
getTableIdentifierExpression( table, creationProcess ),
keyColumnExpression,
simpleFkTarget.getContainingTableExpression(),
simpleFkTarget.getMappedColumnExpression(),
simpleFkTarget.getJdbcMapping()
);
attributeMapping.setForeignKeyDescriptor( foreignKeyDescriptor );
}
else if ( fkTarget instanceof EmbeddableValuedModelPart ) {
if ( bootValueMapping.isReferenceToPrimaryKey() ) {
final EmbeddableValuedModelPart embeddedFkTarget = (EmbeddableValuedModelPart) fkTarget;
final List<String> keyColumnExpressions = new ArrayList<>();
bootValueMapping.getColumnIterator().forEachRemaining(
column ->
keyColumnExpressions.add( column.getText( dialect ) )
);
final List<String> targetColumnExpressions = new ArrayList<>();
embeddedFkTarget.getMappedColumnExpressions().forEach(
column ->
targetColumnExpressions.add( column )
);
final EmbeddedForeignKeyDescriptor embeddedForeignKeyDescriptor = new EmbeddedForeignKeyDescriptor(
attributeMapping.getAttributeName(),
(EmbeddedIdentifierMappingImpl) fkTarget,
getStateArrayContributorMetadataAccess(attributeMapping.getPropertyAccess()),
( (AssociationType) bootValueMapping.getType() ).getForeignKeyDirection(),
getTableIdentifierExpression( bootValueMapping.getTable(), creationProcess ),
keyColumnExpressions,
embeddedFkTarget.getContainingTableExpression(),
targetColumnExpressions,
creationProcess
);
attributeMapping.setForeignKeyDescriptor( embeddedForeignKeyDescriptor );
}
else{
throw new NotYetImplementedFor6Exception();
}
final EmbeddedForeignKeyDescriptor embeddedForeignKeyDescriptor = buildEmbeddedForeignKeyDescriptor(
(EmbeddableValuedModelPart) fkTarget,
attributeMapping,
bootValueMapping,
dialect,
creationProcess
);
attributeMapping.setForeignKeyDescriptor( embeddedForeignKeyDescriptor );
}
else {
throw new NotYetImplementedFor6Exception(
@ -893,6 +862,61 @@ public class MappingModelCreationHelper {
}
}
public static EmbeddedForeignKeyDescriptor buildEmbeddedForeignKeyDescriptor(
EmbeddableValuedModelPart fkTarget,
AbstractAttributeMapping attributeMapping,
Value bootValueMapping,
Dialect dialect,
MappingModelCreationProcess creationProcess) {
final List<String> keyColumnExpressions = new ArrayList<>();
bootValueMapping.getColumnIterator().forEachRemaining(
column ->
keyColumnExpressions.add( column.getText( dialect ) ) );
final List<String> targetColumnExpressions = new ArrayList<>();
fkTarget.getMappedColumnExpressions().forEach(
column ->
targetColumnExpressions.add( column ) );
return new EmbeddedForeignKeyDescriptor(
(EmbeddedIdentifierMappingImpl) fkTarget,
getTableIdentifierExpression( bootValueMapping.getTable(), creationProcess ),
keyColumnExpressions,
fkTarget.getContainingTableExpression(),
targetColumnExpressions,
creationProcess
);
}
private static void setRefererencedAttributeForeignKeyDescriptor(
AbstractAttributeMapping attributeMapping,
SingularAssociationAttributeMapping referencedAttributeMapping,
EntityPersister referencedEntityDescriptor,
String referencedPropertyName,
Dialect dialect,
MappingModelCreationProcess creationProcess) {
ForeignKeyDescriptor foreignKeyDescriptor = referencedAttributeMapping.getForeignKeyDescriptor();
if ( foreignKeyDescriptor == null ) {
PersistentClass entityBinding = creationProcess.getCreationContext()
.getBootModel()
.getEntityBinding(
referencedEntityDescriptor.getEntityName() );
Property property = entityBinding.getProperty( referencedPropertyName );
interpretSingularAssociationAttributeMappingKeyDescriptor(
referencedAttributeMapping,
property,
(ToOne) property.getValue(),
referencedEntityDescriptor,
dialect,
creationProcess
);
attributeMapping.setForeignKeyDescriptor( referencedAttributeMapping.getForeignKeyDescriptor() );
}
else {
attributeMapping.setForeignKeyDescriptor( foreignKeyDescriptor );
}
}
private static String getTableIdentifierExpression(Table table, MappingModelCreationProcess creationProcess) {
final JdbcEnvironment jdbcEnvironment = creationProcess.getCreationContext()
.getMetadata()
@ -1173,7 +1197,7 @@ public class MappingModelCreationHelper {
.getJdbcServices()
.getDialect();
MappingModelCreationHelper.interpretKeyDescriptor(
MappingModelCreationHelper.interpretSingularAssociationAttributeMappingKeyDescriptor(
attributeMapping,
bootProperty,
(ToOne) bootProperty.getValue(),

View File

@ -12,6 +12,7 @@ import java.util.function.Supplier;
import org.hibernate.LockMode;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.CascadeStyle;
@ -62,14 +63,10 @@ import org.hibernate.sql.results.graph.collection.internal.CollectionDomainResul
import org.hibernate.sql.results.graph.collection.internal.DelayedCollectionFetch;
import org.hibernate.sql.results.graph.collection.internal.EagerCollectionFetch;
import org.hibernate.sql.results.graph.collection.internal.SelectEagerCollectionFetch;
import org.hibernate.type.AssociationType;
import org.hibernate.type.EntityType;
import org.hibernate.type.ForeignKeyDirection;
import org.jboss.logging.Logger;
import java.util.ArrayList;
/**
* @author Steve Ebersole
*/
@ -152,7 +149,6 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme
else {
baseIndex = -1;
}
}
@Override
@ -211,47 +207,27 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme
fkBootDescriptorSource = ( (IndexedCollection) bootDescriptor ).getIndex();
}
final Dialect dialect = creationProcess.getCreationContext()
.getSessionFactory()
.getJdbcServices()
.getDialect();
if ( fkTargetPart instanceof BasicValuedModelPart ) {
final BasicValuedModelPart basicFkTargetPart = (BasicValuedModelPart) fkTargetPart;
final Joinable collectionDescriptorAsJoinable = (Joinable) collectionDescriptor;
manyToManyFkDescriptor = new SimpleForeignKeyDescriptor(
ForeignKeyDirection.TO_PARENT,
collectionDescriptorAsJoinable.getTableName(),
fkBootDescriptorSource.getColumnIterator()
.next()
.getText( creationProcess.getCreationContext()
.getSessionFactory()
.getJdbcServices()
.getDialect() ),
fkBootDescriptorSource.getColumnIterator().next().getText( dialect ),
basicFkTargetPart.getContainingTableExpression(),
basicFkTargetPart.getMappedColumnExpression(),
basicFkTargetPart.getJdbcMapping()
);
}
else if ( fkTargetPart instanceof EmbeddableValuedModelPart ) {
final Joinable collectionDescriptorAsJoinable = (Joinable) collectionDescriptor;
java.util.List<String> keyColumnExpressions = new ArrayList<>();
fkBootDescriptorSource.getColumnIterator()
.forEachRemaining( column -> keyColumnExpressions.add(
column.getText( creationProcess.getCreationContext()
.getSessionFactory()
.getJdbcServices()
.getDialect() ) ) );
java.util.List<String> targetColumnExpressions = new ArrayList<>();
fkTargetPart.visitColumns(
(table, column, mapping) ->
targetColumnExpressions.add( column ) );
manyToManyFkDescriptor = new EmbeddedForeignKeyDescriptor(
getAttributeName(),
(EmbeddedIdentifierMappingImpl) fkTargetPart,
stateArrayContributorMetadataAccess,
( (AssociationType) bootDescriptor.getType() ).getForeignKeyDirection(),
collectionDescriptorAsJoinable.getTableName(),
keyColumnExpressions,
( (EmbeddableValuedModelPart) fkTargetPart ).getContainingTableExpression(),
targetColumnExpressions,
manyToManyFkDescriptor = MappingModelCreationHelper.buildEmbeddedForeignKeyDescriptor(
(EmbeddableValuedModelPart) fkTargetPart,
this,
fkBootDescriptorSource,
dialect,
creationProcess
);
}
@ -263,7 +239,6 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme
return true;
}
);
}
final boolean hasOrder = bootDescriptor.getOrderBy() != null;

View File

@ -8,7 +8,6 @@ package org.hibernate.metamodel.mapping.internal;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import org.hibernate.LockMode;
@ -41,7 +40,6 @@ import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.basic.BasicResult;
import org.hibernate.type.ForeignKeyDirection;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
@ -54,34 +52,18 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
private final String targetColumnContainingTable;
private final String targetColumnExpression;
private final JdbcMapping jdbcMapping;
private final ForeignKeyDirection fKeyDirection;
private final int hasCode;
public SimpleForeignKeyDescriptor(
ForeignKeyDirection fKeyDirection,
String keyColumnContainingTable,
String keyColumnExpression,
String targetColumnContainingTable,
String targetColumnExpression,
JdbcMapping jdbcMapping) {
this.fKeyDirection = fKeyDirection;
this.keyColumnContainingTable = keyColumnContainingTable;
this.keyColumnExpression = keyColumnExpression;
this.targetColumnContainingTable = targetColumnContainingTable;
this.targetColumnExpression = targetColumnExpression;
this.jdbcMapping = jdbcMapping;
this.hasCode = Objects.hash(
keyColumnContainingTable,
keyColumnExpression,
targetColumnContainingTable,
targetColumnExpression
);
}
@Override
public ForeignKeyDirection getDirection() {
return fKeyDirection;
}
@Override
@ -100,14 +82,15 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
tableReference,
targetColumnExpression
),
s -> {
return new ColumnReference(
identificationVariable,
targetColumnExpression,
jdbcMapping,
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
);
}
s ->
new ColumnReference(
identificationVariable,
targetColumnExpression,
jdbcMapping,
creationState.getSqlAstCreationState()
.getCreationContext()
.getSessionFactory()
)
),
jdbcMapping.getJavaTypeDescriptor(),
sqlAstCreationState.getCreationContext().getDomainModel().getTypeConfiguration()
@ -397,24 +380,4 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
public String getTargetColumnExpression() {
return targetColumnExpression;
}
@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
SimpleForeignKeyDescriptor that = (SimpleForeignKeyDescriptor) o;
return Objects.equals( keyColumnContainingTable, that.keyColumnContainingTable ) &&
Objects.equals( targetColumnContainingTable, that.targetColumnContainingTable ) &&
Objects.equals( keyColumnExpression, that.keyColumnExpression ) &&
Objects.equals( targetColumnExpression, that.targetColumnExpression );
}
@Override
public int hashCode() {
return this.hasCode;
}
}

View File

@ -76,6 +76,7 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu
private final Cardinality cardinality;
private ForeignKeyDescriptor foreignKeyDescriptor;
private ForeignKeyDirection foreignKeyDirection;
private String identifyingColumnsTableExpression;
public SingularAssociationAttributeMapping(
@ -128,16 +129,14 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu
public void setForeignKeyDescriptor(ForeignKeyDescriptor foreignKeyDescriptor) {
this.foreignKeyDescriptor = foreignKeyDescriptor;
}
final String identifyingColumnsTableExpression;
if ( foreignKeyDescriptor.getDirection() == ForeignKeyDirection.FROM_PARENT && !referringPrimaryKey ) {
identifyingColumnsTableExpression = foreignKeyDescriptor.getTargetTableExpression();
}
else {
identifyingColumnsTableExpression = foreignKeyDescriptor.getReferringTableExpression();
}
public void setIdentifyingColumnsTableExpression(String tableExpression) {
identifyingColumnsTableExpression = tableExpression;
}
this.identifyingColumnsTableExpression = identifyingColumnsTableExpression;
public void setForeignKeyDirection(ForeignKeyDirection direction) {
foreignKeyDirection = direction;
}
public ForeignKeyDescriptor getForeignKeyDescriptor() {

View File

@ -80,6 +80,7 @@ public class ManyToOneEmbeddedIdWithToOneFKTest {
session -> {
System system = session.get( System.class, 1 );
assertThat( system, is( notNullValue() ) );
assertThat( system.getId() , is(1) );
assertTrue( Hibernate.isInitialized( system.getUser() ) );
assertTrue( Hibernate.isInitialized( system.getUser().getPk().subsystem ) );

View File

@ -6,14 +6,21 @@
*/
package org.hibernate.orm.test.onetoone;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.MapsId;
import javax.persistence.OneToOne;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.resource.jdbc.spi.StatementInspector;
import org.hibernate.testing.jdbc.SQLStatementInspector;
import org.hibernate.testing.junit5.EntityManagerFactoryBasedFunctionalTest;
import org.junit.jupiter.api.Test;
@ -25,6 +32,12 @@ import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
*/
public class OneToOneMapsIdJoinColumnTest extends EntityManagerFactoryBasedFunctionalTest {
@Override
protected void applySettings(Map<Object, Object> settings) {
settings.put( AvailableSettings.STATEMENT_INSPECTOR, SQLStatementInspector.class );
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
@ -35,7 +48,12 @@ public class OneToOneMapsIdJoinColumnTest extends EntityManagerFactoryBasedFunct
@Test
public void testLifecycle() {
EntityManagerFactory entityManagerFactory = entityManagerFactory();
SessionFactory sessionFactory = entityManagerFactory.unwrap( SessionFactory.class );
SQLStatementInspector statementInspector = (SQLStatementInspector) sessionFactory.getSessionFactoryOptions().getStatementInspector();
Person _person = doInJPA( this::entityManagerFactory, entityManager -> {
Person person = new Person( "ABC-123" );
PersonDetails details = new PersonDetails();
@ -46,11 +64,16 @@ public class OneToOneMapsIdJoinColumnTest extends EntityManagerFactoryBasedFunct
return person;
} );
statementInspector.clear();
doInJPA( this::entityManagerFactory, entityManager -> {
Person person = entityManager.find( Person.class, _person.getId() );
statementInspector.assertExecutedCount( 1 );
statementInspector.assertNumberOfOccurrenceInQuery( 0, "join", 1 );
statementInspector.clear();
PersonDetails details = entityManager.find( PersonDetails.class, _person.getId() );
statementInspector.assertExecutedCount( 0 );
} );
}