HHH-13725 - Implement ToOne Associations support

This commit is contained in:
Andrea Boriero 2019-11-12 12:07:45 +00:00 committed by Steve Ebersole
parent 403bf9257c
commit ef5db4aa3b
9 changed files with 69 additions and 42 deletions

View File

@ -14,6 +14,7 @@ import org.hibernate.MappingException;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.cfg.annotations.TableBinder;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.KeyValue;
import org.hibernate.mapping.ManyToOne;

View File

@ -16,6 +16,7 @@ import java.util.function.Consumer;
import org.hibernate.LockMode;
import org.hibernate.MappingException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.collection.internal.StandardArraySemantics;
import org.hibernate.collection.internal.StandardBagSemantics;
import org.hibernate.collection.internal.StandardIdentifierBagSemantics;
@ -913,6 +914,7 @@ public class MappingModelCreationHelper {
final ModelPart fkTarget;
if ( bootValueMapping.isReferenceToPrimaryKey() ) {
referencedEntityDescriptor.prepareMappingModel( creationProcess );
fkTarget = referencedEntityDescriptor.getIdentifierMapping();
}
else {
@ -924,15 +926,26 @@ public class MappingModelCreationHelper {
if ( fkTarget instanceof BasicValuedModelPart ) {
final BasicValuedModelPart simpleFkTarget = (BasicValuedModelPart) fkTarget;
final Iterator<Selectable> columnIterator = bootValueMapping.getColumnIterator();
String keyColumnExpression;
final Identifier identifier = creationProcess.getCreationContext()
.getBootstrapContext()
.getMetadataBuildingOptions()
.getPhysicalNamingStrategy().toPhysicalTableName(
bootValueMapping.getTable().getNameIdentifier(),
jdbcServices.getJdbcEnvironment()
);
if ( columnIterator.hasNext() ) {
keyColumnExpression = columnIterator.next().getText( dialect );
}
else {
// case of ToOne with @PrimaryKeyJoinColumn
keyColumnExpression = identifier.getText();
}
return new SimpleForeignKeyDescriptor(
creationProcess.getCreationContext()
.getBootstrapContext()
.getMetadataBuildingOptions()
.getPhysicalNamingStrategy().toPhysicalTableName(
bootValueMapping.getTable().getNameIdentifier(),
jdbcServices.getJdbcEnvironment()
).getText(),
bootValueMapping.getColumnIterator().next().getText( dialect ),
identifier.getText(),
keyColumnExpression,
simpleFkTarget.getContainingTableExpression(),
simpleFkTarget.getMappedColumnExpression(),
simpleFkTarget.getJdbcMapping()

View File

@ -6,11 +6,7 @@
*/
package org.hibernate.metamodel.mapping.internal;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.LockMode;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.engine.FetchTiming;
import org.hibernate.metamodel.mapping.EntityMappingType;
@ -27,15 +23,14 @@ import org.hibernate.sql.ast.spi.SqlAliasStemHelper;
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.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableGroupBuilder;
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
import org.hibernate.sql.ast.tree.from.TableReferenceCollector;
import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.sql.results.internal.domain.entity.DelayedEntityFetch;
import org.hibernate.sql.results.internal.domain.entity.EntityFetchImpl;
import org.hibernate.sql.results.spi.DomainResult;
import org.hibernate.sql.results.spi.DomainResultCreationState;
import org.hibernate.sql.results.spi.Fetch;
import org.hibernate.sql.results.spi.FetchParent;
@ -78,7 +73,7 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu
@Override
public EntityMappingType getEntityMappingType() {
return (EntityMappingType)getMappedTypeDescriptor();
return getMappedTypeDescriptor();
}
@Override
@ -96,24 +91,26 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu
TableGroup lhsTableGroup = sqlAstCreationState.getFromClauseAccess()
.getTableGroup( fetchParent.getNavigablePath() );
// todo (6.0) : determine the correct JoinType
final TableGroupJoin tableGroupJoin = createTableGroupJoin(
fetchablePath,
lhsTableGroup,
null,
JoinType.INNER,
lockMode,
creationState.getSqlAliasBaseManager(),
creationState.getSqlAstCreationState().getSqlExpressionResolver(),
creationState.getSqlAstCreationState().getCreationContext()
);
if ( sqlAstCreationState.getFromClauseAccess().findTableGroup( fetchablePath ) == null ) {
// todo (6.0) : determine the correct JoinType
final TableGroupJoin tableGroupJoin = createTableGroupJoin(
fetchablePath,
lhsTableGroup,
null,
JoinType.INNER,
lockMode,
creationState.getSqlAliasBaseManager(),
creationState.getSqlAstCreationState().getSqlExpressionResolver(),
creationState.getSqlAstCreationState().getCreationContext()
);
lhsTableGroup.addTableGroupJoin( tableGroupJoin );
lhsTableGroup.addTableGroupJoin( tableGroupJoin );
sqlAstCreationState.getFromClauseAccess().registerTableGroup(
fetchablePath,
tableGroupJoin.getJoinedGroup()
);
sqlAstCreationState.getFromClauseAccess().registerTableGroup(
fetchablePath,
tableGroupJoin.getJoinedGroup()
);
}
return new EntityFetchImpl(
fetchParent,
@ -182,6 +179,15 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu
lhs.addTableGroupJoin( tableGroupJoin );
final Predicate predicate = foreignKeyDescriptor.generateJoinPredicate(
lhs,
tableGroup,
joinType,
sqlExpressionResolver,
creationContext
);
tableGroupJoin.applyPredicate( predicate );
return tableGroupJoin;
}

View File

@ -6198,8 +6198,6 @@ public abstract class AbstractEntityPersister
accessOptimizer = null;
}
final SessionFactoryImplementor sessionFactory = creationContext.getSessionFactory();
if ( isMultiTable() ) {
sqmMultiTableMutationStrategy = interpretSqmMultiTableStrategy(
this,

View File

@ -56,6 +56,7 @@ public abstract class AbstractColumnReferenceQualifier implements ColumnReferenc
return tableJoin.getJoinedTableReference();
}
}
return null;
}

View File

@ -64,10 +64,16 @@ public class StandardTableGroup extends AbstractTableGroup {
if ( tableReference == null ) {
for ( TableReferenceJoin tableJoin : tableJoins ) {
if ( tableJoin.getJoinedTableReference().getTableExpression().equals( tableExpression ) ) {
tableReference = tableJoin.getJoinedTableReference();
return tableJoin.getJoinedTableReference();
}
}
}
for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference();
if ( primaryTableReference.getTableExpression().equals( tableExpression ) ) {
return primaryTableReference;
}
}
return tableReference;
}
}

View File

@ -6,19 +6,16 @@
*/
package org.hibernate.sql.results.internal.domain.entity;
import java.util.ArrayList;
import java.util.function.Consumer;
import org.hibernate.LockMode;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.metamodel.mapping.internal.SingularAssociationAttributeMapping;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.results.internal.domain.AbstractFetchParentAccess;
import org.hibernate.sql.results.spi.AssemblerCreationState;
import org.hibernate.sql.results.spi.DomainResult;
import org.hibernate.sql.results.spi.DomainResultAssembler;
import org.hibernate.sql.results.spi.DomainResultCreationState;
import org.hibernate.sql.results.spi.EntityInitializer;
@ -81,7 +78,7 @@ public class DelayedEntityFetch implements Fetch {
FetchParentAccess parentAccess,
Consumer<Initializer> collector,
AssemblerCreationState creationState) {
EntityInitializer entityInitializer = new DelayedEntityFectInitializer(
EntityInitializer entityInitializer = new DelayedEntityFetchInitializer(
parentAccess,
navigablePath,
(EntityPersister) fetchedAttribute.getMappedTypeDescriptor()
@ -91,7 +88,7 @@ public class DelayedEntityFetch implements Fetch {
}
private static class DelayedEntityFectInitializer extends AbstractFetchParentAccess implements EntityInitializer {
private static class DelayedEntityFetchInitializer extends AbstractFetchParentAccess implements EntityInitializer {
private final FetchParentAccess parentAccess;
private final NavigablePath navigablePath;
@ -99,7 +96,7 @@ public class DelayedEntityFetch implements Fetch {
private Object entityInstance;
protected DelayedEntityFectInitializer(
protected DelayedEntityFetchInitializer(
FetchParentAccess parentAccess,
NavigablePath fetchedNavigable,
EntityPersister concreteDescriptor

View File

@ -52,8 +52,12 @@ public class EntityFetchImpl implements Fetch {
this.navigablePath = navigablePath;
this.fkResult = fkResult;
entityResult = new EntityResultImpl( navigablePath,
(EntityValuedModelPart) fetchedAttribute.getMappedTypeDescriptor(), null, creationState );
entityResult = new EntityResultImpl(
navigablePath,
(EntityValuedModelPart) fetchedAttribute.getMappedTypeDescriptor(),
null,
creationState
);
}

View File

@ -75,6 +75,7 @@ public class ManyToOneTest {
session -> {
SimpleEntity simpleEntity = new SimpleEntity();
simpleEntity.setId( 1 );
simpleEntity.setName( "Fab" );
session.save( simpleEntity );
OtherEntity otherEntity = new OtherEntity();
otherEntity.setId( 2 );