HHH-13725 - Implement ToOne Associations support
This commit is contained in:
parent
403bf9257c
commit
ef5db4aa3b
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -6198,8 +6198,6 @@ public abstract class AbstractEntityPersister
|
|||
accessOptimizer = null;
|
||||
}
|
||||
|
||||
final SessionFactoryImplementor sessionFactory = creationContext.getSessionFactory();
|
||||
|
||||
if ( isMultiTable() ) {
|
||||
sqmMultiTableMutationStrategy = interpretSqmMultiTableStrategy(
|
||||
this,
|
||||
|
|
|
@ -56,6 +56,7 @@ public abstract class AbstractColumnReferenceQualifier implements ColumnReferenc
|
|||
return tableJoin.getJoinedTableReference();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue