Skip to content

Commit

Permalink
Fix joined subclass wrong table for id and version columns
Browse files Browse the repository at this point in the history
  • Loading branch information
dreab8 committed Sep 7, 2020
1 parent f1ac2f8 commit 8fe4b40
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 108 deletions.
Expand Up @@ -185,7 +185,6 @@ private boolean finishInitialization(
final Selectable selectable = basicValue.getColumn();

final String mappedColumnExpression = mappedColumnExpressions.get( columnPosition++ );
assert mappedColumnExpression.equals( selectable.getText( sessionFactory.getDialect() ) );

attributeMappings.put(
bootPropertyDescriptor.getName(),
Expand Down
Expand Up @@ -65,8 +65,6 @@
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.lock.LockingStrategy;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.OptimisticLockStyle;
import org.hibernate.engine.internal.CacheHelper;
Expand Down Expand Up @@ -228,7 +226,6 @@
import org.hibernate.type.VersionType;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.spi.TypeConfiguration;

/**
* Basic functionality for persisting an entity via JDBC
Expand Down Expand Up @@ -1367,29 +1364,7 @@ protected TableReference resolvePrimaryTableReference(SqlAliasBase sqlAliasBase)
);
}

protected TableReferenceJoin createTableReferenceJoin(
int subClassTablePosition,
TableReference rootTableReference,
SqlAstJoinType sqlAstJoinType,
SqlAliasBase sqlAliasBase,
SqlExpressionResolver sqlExpressionResolver) {
final boolean nullable = isNullableSubclassTable( subClassTablePosition );

final TableReference joinedTableReference = new TableReference(
getSubclassTableName( subClassTablePosition ),
sqlAliasBase.generateNewAlias(),
nullable,
getFactory()
);

return new TableReferenceJoin(
nullable ? SqlAstJoinType.LEFT : sqlAstJoinType,
joinedTableReference,
generateJoinPredicate( rootTableReference, joinedTableReference, subClassTablePosition, sqlExpressionResolver )
);
}

private Predicate generateJoinPredicate(
protected Predicate generateJoinPredicate(
TableReference rootTableReference,
TableReference joinedTableReference,
int subClassTablePosition,
Expand Down Expand Up @@ -5799,8 +5774,8 @@ public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version,
private EntityRowIdMapping rowIdMapping;
private EntityDiscriminatorMapping discriminatorMapping;

private Map<String, AttributeMapping> declaredAttributeMappings = new LinkedHashMap<>();
private List<AttributeMapping> attributeMappings;
protected Map<String, AttributeMapping> declaredAttributeMappings = new LinkedHashMap<>();
protected List<Fetchable> staticFetchableList;

protected ReflectionOptimizer.AccessOptimizer accessOptimizer;
Expand All @@ -5822,53 +5797,21 @@ public void prepareMappingModel(MappingModelCreationProcess creationProcess) {
.getBootModel()
.getEntityBinding( getEntityName() );

if ( superMappingType != null && shouldProcessSuperMapping() ) {
if ( superMappingType != null ) {
( (InFlightEntityMappingType) superMappingType ).prepareMappingModel( creationProcess );

this.identifierMapping = superMappingType.getIdentifierMapping();
this.versionMapping = superMappingType.getVersionMapping();
this.rowIdMapping = superMappingType.getRowIdMapping();
this.naturalIdMapping = superMappingType.getNaturalIdMapping();
this.discriminatorMapping = superMappingType.getDiscriminatorMapping();
}
else {
identifierMapping = creationProcess.processSubPart(
EntityIdentifierMapping.ROLE_LOCAL_NAME,
(role, creationProcess1) ->
generateIdentifierMapping( creationProcess, bootEntityDescriptor )
);

if ( getVersionType() == null ) {
versionMapping = null;
}
else {
final int versionPropertyIndex = getVersionProperty();
final String versionPropertyName = getPropertyNames()[ versionPropertyIndex ];

versionMapping = creationProcess.processSubPart(
versionPropertyName,
(role, creationProcess1) -> generateVersionMapping(
this,
(RootClass) bootEntityDescriptor,
creationProcess
)
);
}

if ( rowIdName == null ) {
rowIdMapping = null;
if ( shouldProcessSuperMapping() ) {
this.discriminatorMapping = superMappingType.getDiscriminatorMapping();
this.identifierMapping = superMappingType.getIdentifierMapping();
this.naturalIdMapping = superMappingType.getNaturalIdMapping();
this.versionMapping = superMappingType.getVersionMapping();
this.rowIdMapping = superMappingType.getRowIdMapping();
}
else {
rowIdMapping = creationProcess.processSubPart(
rowIdName,
(role, creationProcess1) -> new EntityRowIdMappingImpl( rowIdName, this.getTableName(), this)
);
prepareMappingModel( creationProcess, bootEntityDescriptor );
}

buildDiscriminatorMapping();

// todo (6.0) : support for natural-id not yet implemented
naturalIdMapping = null;
}
else {
prepareMappingModel( creationProcess, bootEntityDescriptor );
}

final EntityMetamodel currentEntityMetamodel = this.getEntityMetamodel();
Expand Down Expand Up @@ -5923,13 +5866,37 @@ public void prepareMappingModel(MappingModelCreationProcess creationProcess) {
"Entity(" + getEntityName() + ") `staticFetchableList` generator",
() -> {
staticFetchableList = new ArrayList<>( attributeMappings.size() );
visitAttributeMappings( attributeMapping -> staticFetchableList.add( (Fetchable) attributeMapping ) );
visitSubTypeAttributeMappings( attributeMapping -> staticFetchableList.add( (Fetchable) attributeMapping ) );
visitAttributeMappings( attributeMapping -> staticFetchableList.add( attributeMapping ) );
visitSubTypeAttributeMappings( attributeMapping -> staticFetchableList.add( attributeMapping ) );
return true;
}
);
}

private void prepareMappingModel(MappingModelCreationProcess creationProcess, PersistentClass bootEntityDescriptor) {
identifierMapping = creationProcess.processSubPart(
EntityIdentifierMapping.ROLE_LOCAL_NAME,
(role, process) ->
generateIdentifierMapping( process, bootEntityDescriptor )
);

versionMapping = generateVersionMapping( creationProcess, bootEntityDescriptor );

if ( rowIdName == null ) {
rowIdMapping = null;
}
else {
rowIdMapping = creationProcess.processSubPart(
rowIdName,
(role, process) -> new EntityRowIdMappingImpl( rowIdName, this.getTableName(), this)
);
}
// todo (6.0) : support for natural-id not yet implemented
naturalIdMapping = null;

discriminatorMapping = generateDiscriminatorMapping();
}

protected static SqmMultiTableMutationStrategy interpretSqmMultiTableStrategy(
AbstractEntityPersister entityMappingDescriptor,
MappingModelCreationProcess creationProcess) {
Expand Down Expand Up @@ -5970,12 +5937,12 @@ protected int getStateArrayInitialPosition(MappingModelCreationProcess creationP
return stateArrayPosition;
}

protected void buildDiscriminatorMapping() {
protected EntityDiscriminatorMapping generateDiscriminatorMapping() {
if ( getDiscriminatorType() == null) {
discriminatorMapping = null;
return null;
}
else {
discriminatorMapping = new EntityDiscriminatorMappingImpl(
return new EntityDiscriminatorMappingImpl(
this,
getTableName(),
getDiscriminatorColumnReaders(),
Expand All @@ -5984,6 +5951,27 @@ protected void buildDiscriminatorMapping() {
}
}

protected EntityVersionMapping generateVersionMapping(
MappingModelCreationProcess creationProcess,
PersistentClass bootEntityDescriptor) {
if ( getVersionType() == null ) {
return null;
}
else {
final int versionPropertyIndex = getVersionProperty();
final String versionPropertyName = getPropertyNames()[ versionPropertyIndex ];

return creationProcess.processSubPart(
versionPropertyName,
(role, creationProcess1) -> generateVersionMapping(
this,
bootEntityDescriptor,
creationProcess
)
);
}
}

protected boolean shouldProcessSuperMapping(){
return true;
}
Expand Down Expand Up @@ -6056,7 +6044,7 @@ public boolean isTypeOrSuperType(EntityMappingType targetType) {
}


private EntityIdentifierMapping generateIdentifierMapping(MappingModelCreationProcess creationProcess, PersistentClass bootEntityDescriptor) {
protected EntityIdentifierMapping generateIdentifierMapping(MappingModelCreationProcess creationProcess, PersistentClass bootEntityDescriptor) {
final Type idType = getIdentifierType();

if ( idType instanceof CompositeType ) {
Expand Down Expand Up @@ -6094,7 +6082,7 @@ private EntityIdentifierMapping generateIdentifierMapping(MappingModelCreationPr
);
}

private EntityIdentifierMapping generateNonEncapsulatedCompositeIdentifierMapping(
protected EntityIdentifierMapping generateNonEncapsulatedCompositeIdentifierMapping(
MappingModelCreationProcess creationProcess,
PersistentClass bootEntityDescriptor,
CompositeType cidType) {
Expand All @@ -6116,9 +6104,9 @@ private EntityIdentifierMapping generateNonEncapsulatedCompositeIdentifierMappin
* @param bootModelRootEntityDescriptor The boot-time entity descriptor for the "root entity" in the hierarchy
* @param creationProcess The SF creation process - access to useful things
*/
private static EntityVersionMapping generateVersionMapping(
protected static EntityVersionMapping generateVersionMapping(
AbstractEntityPersister entityPersister,
RootClass bootModelRootEntityDescriptor,
PersistentClass bootModelRootEntityDescriptor,
MappingModelCreationProcess creationProcess) {
final BasicValue bootModelVersionValue = (BasicValue) bootModelRootEntityDescriptor.getVersion().getValue();
final BasicValue.Resolution<?> basicTypeResolution = bootModelVersionValue.resolve();
Expand Down Expand Up @@ -6595,16 +6583,6 @@ public void generateEntityDefinition() {
collectAttributeDefinitions();
}

@Override
public void visitJdbcTypes(
Consumer<JdbcMapping> action,
Clause clause,
TypeConfiguration typeConfiguration) {
getAttributeMappings().forEach(
attributeMapping -> attributeMapping.visitJdbcTypes( action, clause, typeConfiguration )
);
}

@Override
public void visitJdbcValues(
Object value,
Expand Down

0 comments on commit 8fe4b40

Please sign in to comment.