HHH-16117 Querying entity with collection in Embeddable causes 'A collection with cascade=all-delete-orphan was no longer referenced by the owning entity instance'
This commit is contained in:
parent
7b6d158245
commit
974afe26f0
|
@ -18,10 +18,13 @@ import org.hibernate.engine.spi.EntityKey;
|
|||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.Status;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.NaturalIdMapping;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.AbstractEntityPersister;
|
||||
import org.hibernate.persister.entity.AttributeMappingsList;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
import static org.hibernate.engine.internal.Versioning.getVersion;
|
||||
|
@ -148,20 +151,69 @@ public abstract class AbstractEntityInsertAction extends EntityAction {
|
|||
|
||||
protected void addCollectionsByKeyToPersistenceContext(PersistenceContext persistenceContext, Object[] objects) {
|
||||
for ( int i = 0; i < objects.length; i++ ) {
|
||||
if ( objects[i] instanceof PersistentCollection<?> ) {
|
||||
final PersistentCollection<?> persistentCollection = (PersistentCollection<?>) objects[i];
|
||||
final CollectionPersister collectionPersister = ( (PluralAttributeMapping) getPersister().getAttributeMapping( i ) ).getCollectionDescriptor();
|
||||
final CollectionKey collectionKey = new CollectionKey(
|
||||
collectionPersister,
|
||||
( (AbstractEntityPersister) getPersister() ).getCollectionKey(
|
||||
collectionPersister,
|
||||
getInstance(),
|
||||
persistenceContext.getEntry( getInstance() ),
|
||||
getSession()
|
||||
)
|
||||
final AttributeMapping attributeMapping = getPersister().getAttributeMapping( i );
|
||||
if ( attributeMapping.isEmbeddedAttributeMapping() ) {
|
||||
visitEmbeddedAttributeMapping(
|
||||
attributeMapping.asEmbeddedAttributeMapping(),
|
||||
objects[i],
|
||||
persistenceContext
|
||||
);
|
||||
persistenceContext.addCollectionByKey( collectionKey, persistentCollection );
|
||||
}
|
||||
else if ( attributeMapping.isPluralAttributeMapping() ) {
|
||||
addCollectionKey(
|
||||
attributeMapping.asPluralAttributeMapping(),
|
||||
objects[i],
|
||||
persistenceContext
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void visitEmbeddedAttributeMapping(
|
||||
EmbeddedAttributeMapping attributeMapping,
|
||||
Object object,
|
||||
PersistenceContext persistenceContext) {
|
||||
if ( object != null ) {
|
||||
final AttributeMappingsList attributeMappings = attributeMapping.getEmbeddableTypeDescriptor().getAttributeMappings();
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final AttributeMapping attribute = attributeMappings.get( i );
|
||||
if ( attribute.isPluralAttributeMapping() ) {
|
||||
addCollectionKey(
|
||||
attribute.asPluralAttributeMapping(),
|
||||
attribute.getPropertyAccess().getGetter().get( object ),
|
||||
persistenceContext
|
||||
);
|
||||
}
|
||||
else if ( attribute.isEmbeddedAttributeMapping() ) {
|
||||
visitEmbeddedAttributeMapping(
|
||||
attribute.asEmbeddedAttributeMapping(),
|
||||
attribute.getPropertyAccess().getGetter().get( object ),
|
||||
persistenceContext
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addCollectionKey(
|
||||
PluralAttributeMapping pluralAttributeMapping,
|
||||
Object o,
|
||||
PersistenceContext persistenceContext) {
|
||||
if ( o instanceof PersistentCollection ) {
|
||||
final CollectionPersister collectionPersister = pluralAttributeMapping.getCollectionDescriptor();
|
||||
final CollectionKey collectionKey = new CollectionKey(
|
||||
collectionPersister,
|
||||
( (AbstractEntityPersister) getPersister() ).getCollectionKey(
|
||||
collectionPersister,
|
||||
getInstance(),
|
||||
persistenceContext.getEntry( getInstance() ),
|
||||
getSession()
|
||||
)
|
||||
);
|
||||
persistenceContext.addCollectionByKey(
|
||||
collectionKey,
|
||||
(PersistentCollection<?>) o
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ public class EntityInsertAction extends AbstractEntityInsertAction {
|
|||
final EntityPersister persister = getPersister();
|
||||
final Object instance = getInstance();
|
||||
persister.insert( id, getState(), instance, session );
|
||||
PersistenceContext persistenceContext = session.getPersistenceContextInternal();
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
|
||||
final EntityEntry entry = persistenceContext.getEntry( instance );
|
||||
if ( entry == null ) {
|
||||
throw new AssertionFailure( "possible non-threadsafe access to session" );
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.mapping;
|
||||
|
||||
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.sql.results.graph.DatabaseSnapshotContributor;
|
||||
import org.hibernate.sql.results.graph.Fetchable;
|
||||
|
@ -92,4 +93,30 @@ public interface AttributeMapping
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility method to avoid casting explicitly to PluralAttributeMapping
|
||||
*
|
||||
* @return PluralAttributeMapping if this is an instance of PluralAttributeMapping otherwise {@code null}
|
||||
*/
|
||||
default PluralAttributeMapping asPluralAttributeMapping() {
|
||||
return null;
|
||||
}
|
||||
|
||||
default boolean isPluralAttributeMapping() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility method to avoid casting explicitly to EmbeddedAttributeMapping
|
||||
*
|
||||
* @return EmbeddedAttributeMapping if this is an instance of EmbeddedAttributeMapping otherwise {@code null}
|
||||
*/
|
||||
default EmbeddedAttributeMapping asEmbeddedAttributeMapping(){
|
||||
return null;
|
||||
}
|
||||
|
||||
default boolean isEmbeddedAttributeMapping(){
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -175,4 +175,14 @@ public interface PluralAttributeMapping
|
|||
SqlAstCreationState creationState) {
|
||||
getCollectionDescriptor().applyWhereRestrictions( predicateConsumer, tableGroup, useQualifier, creationState );
|
||||
}
|
||||
|
||||
@Override
|
||||
default PluralAttributeMapping asPluralAttributeMapping() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isPluralAttributeMapping() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -437,4 +437,14 @@ public class EmbeddedAttributeMapping
|
|||
}
|
||||
return parentInjectionAttributePropertyAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddedAttributeMapping asEmbeddedAttributeMapping() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmbeddedAttributeMapping() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue