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.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping;
@ -149,7 +150,16 @@ public class TemporaryTable implements Exportable, Contributable {
if ( pluralAttribute.getSeparateCollectionTable() != null ) { if ( pluralAttribute.getSeparateCollectionTable() != null ) {
// Ensure that the FK target columns are available // 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 ) ) { if ( !( fkTarget instanceof EntityIdentifierMapping ) ) {
final Value value = entityBinding.getSubclassProperty( pluralAttribute.getAttributeName() ) final Value value = entityBinding.getSubclassProperty( pluralAttribute.getAttributeName() )
.getValue(); .getValue();

View File

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

View File

@ -213,7 +213,12 @@ public class EntityCollectionPart
.getAssociatedEntityPersister( creationProcess.getCreationContext().getSessionFactory() ); .getAssociatedEntityPersister( creationProcess.getCreationContext().getSessionFactory() );
fkTargetModelPart = elementPersister.findByPath( mapKeyPropertyName ); fkTargetModelPart = elementPersister.findByPath( mapKeyPropertyName );
if ( fkTargetModelPart == null ) { 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() ) { if ( collectionDescriptor.isOneToMany() && mappedByProperty != null && !mappedByProperty.isEmpty() ) {
fkTargetModelPart = entityMappingType.findByPath( mappedByProperty ); fkTargetModelPart = entityMappingType.findByPath( mappedByProperty );
if ( fkTargetModelPart == null ) { 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 { else {
@ -261,7 +271,7 @@ public class EntityCollectionPart
if ( fkTargetModelPart instanceof ToOneAttributeMapping ) { if ( fkTargetModelPart instanceof ToOneAttributeMapping ) {
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) fkTargetModelPart; final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) fkTargetModelPart;
if ( toOneAttributeMapping.getForeignKeyDescriptor() == null ) { if ( toOneAttributeMapping.getForeignKeyDescriptor() == null ) {
throw new RuntimeException( "Not yet ready: " + toOneAttributeMapping ); throw new IllegalStateException( "Not yet ready: " + toOneAttributeMapping );
} }
return toOneAttributeMapping.getForeignKeyDescriptor(); return toOneAttributeMapping.getForeignKeyDescriptor();
} }

View File

@ -149,32 +149,44 @@ public class VirtualIdEmbeddable extends AbstractEmbeddableMapping implements Id
@Override @Override
public SelectableMapping getSelectable(int columnIndex) { public SelectableMapping getSelectable(int columnIndex) {
return selectableMappings.getSelectable( columnIndex ); return getSelectableMappings().getSelectable( columnIndex );
} }
@Override @Override
public int forEachSelectable(SelectableConsumer consumer) { public int forEachSelectable(SelectableConsumer consumer) {
return selectableMappings.forEachSelectable( 0, consumer ); return getSelectableMappings().forEachSelectable( 0, consumer );
} }
@Override @Override
public int forEachSelectable(int offset, SelectableConsumer consumer) { public int forEachSelectable(int offset, SelectableConsumer consumer) {
return selectableMappings.forEachSelectable( offset, consumer ); return getSelectableMappings().forEachSelectable( offset, consumer );
} }
@Override @Override
public int getJdbcTypeCount() { public int getJdbcTypeCount() {
return selectableMappings.getJdbcTypeCount(); return getSelectableMappings().getJdbcTypeCount();
} }
@Override @Override
public List<JdbcMapping> getJdbcMappings() { 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 @Override
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) { public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
return selectableMappings.forEachSelectable( return getSelectableMappings().forEachSelectable(
offset, offset,
(index, selectable) -> action.accept( index, selectable.getJdbcMapping() ) (index, selectable) -> action.accept( index, selectable.getJdbcMapping() )
); );