catch other cases where NPE indicates that a PostInitCallbackEntry is unready

This commit is contained in:
Gavin King 2022-02-10 14:05:14 +01:00
parent 9a98976b41
commit 74e1e6caad
4 changed files with 54 additions and 12 deletions

View File

@ -31,6 +31,7 @@ import org.hibernate.mapping.Value;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
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.ModelPart;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
@ -149,7 +150,16 @@ public class TemporaryTable implements Exportable, Contributable {
if ( pluralAttribute.getSeparateCollectionTable() != null ) {
// Ensure that the FK target columns are available
final ModelPart fkTarget = pluralAttribute.getKeyDescriptor().getTargetPart();
ForeignKeyDescriptor keyDescriptor = pluralAttribute.getKeyDescriptor();
if ( keyDescriptor==null ) {
// This is expected to happen when processing a
// PostInitCallbackEntry because the callbacks
// are not ordered. The exception is caught in
// MappingModelCreationProcess.executePostInitCallbacks()
// and the callback is re-queued.
throw new IllegalStateException( "Not yet ready: " + pluralAttribute );
}
final ModelPart fkTarget = keyDescriptor.getTargetPart();
if ( !( fkTarget instanceof EntityIdentifierMapping ) ) {
final Value value = entityBinding.getSubclassProperty( pluralAttribute.getAttributeName() )
.getValue();

View File

@ -38,6 +38,7 @@ import org.hibernate.metamodel.mapping.AttributeMapping;
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.ManagedMappingType;
import org.hibernate.metamodel.mapping.ModelPart;
@ -195,6 +196,15 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
}
else if ( attributeMapping instanceof ToOneAttributeMapping ) {
final ToOneAttributeMapping original = (ToOneAttributeMapping) attributeMapping;
ForeignKeyDescriptor foreignKeyDescriptor = original.getForeignKeyDescriptor();
if ( foreignKeyDescriptor==null ) {
// This is expected to happen when processing a
// PostInitCallbackEntry because the callbacks
// are not ordered. The exception is caught in
// MappingModelCreationProcess.executePostInitCallbacks()
// and the callback is re-queued.
throw new IllegalStateException( "Not yet ready: " + original );
}
final ToOneAttributeMapping toOne = original.copy(
declaringType,
declaringTableGroupProducer
@ -204,7 +214,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
selectableMappings.getSelectable( offset ).getContainingTableExpression()
);
toOne.setForeignKeyDescriptor(
original.getForeignKeyDescriptor().withKeySelectionMapping(
foreignKeyDescriptor.withKeySelectionMapping(
declaringType,
declaringTableGroupProducer,
index -> selectableMappings.getSelectable( offset + index ),
@ -704,7 +714,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
// are not ordered. The exception is caught in
// MappingModelCreationProcess.executePostInitCallbacks()
// and the callback is re-queued.
throw new IllegalStateException("not yet ready");
throw new IllegalStateException("Not yet ready");
}
return selectableMappings;
}

View File

@ -213,7 +213,12 @@ public class EntityCollectionPart
.getAssociatedEntityPersister( creationProcess.getCreationContext().getSessionFactory() );
fkTargetModelPart = elementPersister.findByPath( mapKeyPropertyName );
if ( fkTargetModelPart == null ) {
throw new RuntimeException( "Couldn't find model part for path [" + mapKeyPropertyName + "] on entity: " + elementPersister.getEntityName() );
// This is expected to happen when processing a
// PostInitCallbackEntry because the callbacks
// are not ordered. The exception is caught in
// MappingModelCreationProcess.executePostInitCallbacks()
// and the callback is re-queued.
throw new IllegalStateException( "Couldn't find model part for path [" + mapKeyPropertyName + "] on entity: " + elementPersister.getEntityName() );
}
}
}
@ -222,7 +227,12 @@ public class EntityCollectionPart
if ( collectionDescriptor.isOneToMany() && mappedByProperty != null && !mappedByProperty.isEmpty() ) {
fkTargetModelPart = entityMappingType.findByPath( mappedByProperty );
if ( fkTargetModelPart == null ) {
throw new RuntimeException( "Couldn't find model part for path [" + mappedByProperty + "] on entity: " + entityMappingType.getEntityName() );
// This is expected to happen when processing a
// PostInitCallbackEntry because the callbacks
// are not ordered. The exception is caught in
// MappingModelCreationProcess.executePostInitCallbacks()
// and the callback is re-queued.
throw new IllegalStateException( "Couldn't find model part for path [" + mappedByProperty + "] on entity: " + entityMappingType.getEntityName() );
}
}
else {
@ -261,7 +271,7 @@ public class EntityCollectionPart
if ( fkTargetModelPart instanceof ToOneAttributeMapping ) {
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) fkTargetModelPart;
if ( toOneAttributeMapping.getForeignKeyDescriptor() == null ) {
throw new RuntimeException( "Not yet ready: " + toOneAttributeMapping );
throw new IllegalStateException( "Not yet ready: " + toOneAttributeMapping );
}
return toOneAttributeMapping.getForeignKeyDescriptor();
}

View File

@ -149,32 +149,44 @@ public class VirtualIdEmbeddable extends AbstractEmbeddableMapping implements Id
@Override
public SelectableMapping getSelectable(int columnIndex) {
return selectableMappings.getSelectable( columnIndex );
return getSelectableMappings().getSelectable( columnIndex );
}
@Override
public int forEachSelectable(SelectableConsumer consumer) {
return selectableMappings.forEachSelectable( 0, consumer );
return getSelectableMappings().forEachSelectable( 0, consumer );
}
@Override
public int forEachSelectable(int offset, SelectableConsumer consumer) {
return selectableMappings.forEachSelectable( offset, consumer );
return getSelectableMappings().forEachSelectable( offset, consumer );
}
@Override
public int getJdbcTypeCount() {
return selectableMappings.getJdbcTypeCount();
return getSelectableMappings().getJdbcTypeCount();
}
@Override
public List<JdbcMapping> getJdbcMappings() {
return selectableMappings.getJdbcMappings();
return getSelectableMappings().getJdbcMappings();
}
private SelectableMappings getSelectableMappings() {
if (selectableMappings == null) {
// This is expected to happen when processing a
// PostInitCallbackEntry because the callbacks
// are not ordered. The exception is caught in
// MappingModelCreationProcess.executePostInitCallbacks()
// and the callback is re-queued.
throw new IllegalStateException("Not yet ready");
}
return selectableMappings;
}
@Override
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
return selectableMappings.forEachSelectable(
return getSelectableMappings().forEachSelectable(
offset,
(index, selectable) -> action.accept( index, selectable.getJdbcMapping() )
);