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.PersistenceContext;
|
||||||
import org.hibernate.engine.spi.Status;
|
import org.hibernate.engine.spi.Status;
|
||||||
import org.hibernate.event.spi.EventSource;
|
import org.hibernate.event.spi.EventSource;
|
||||||
|
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.NaturalIdMapping;
|
import org.hibernate.metamodel.mapping.NaturalIdMapping;
|
||||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.persister.entity.AbstractEntityPersister;
|
import org.hibernate.persister.entity.AbstractEntityPersister;
|
||||||
|
import org.hibernate.persister.entity.AttributeMappingsList;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
import static org.hibernate.engine.internal.Versioning.getVersion;
|
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) {
|
protected void addCollectionsByKeyToPersistenceContext(PersistenceContext persistenceContext, Object[] objects) {
|
||||||
for ( int i = 0; i < objects.length; i++ ) {
|
for ( int i = 0; i < objects.length; i++ ) {
|
||||||
if ( objects[i] instanceof PersistentCollection<?> ) {
|
final AttributeMapping attributeMapping = getPersister().getAttributeMapping( i );
|
||||||
final PersistentCollection<?> persistentCollection = (PersistentCollection<?>) objects[i];
|
if ( attributeMapping.isEmbeddedAttributeMapping() ) {
|
||||||
final CollectionPersister collectionPersister = ( (PluralAttributeMapping) getPersister().getAttributeMapping( i ) ).getCollectionDescriptor();
|
visitEmbeddedAttributeMapping(
|
||||||
final CollectionKey collectionKey = new CollectionKey(
|
attributeMapping.asEmbeddedAttributeMapping(),
|
||||||
collectionPersister,
|
objects[i],
|
||||||
( (AbstractEntityPersister) getPersister() ).getCollectionKey(
|
persistenceContext
|
||||||
collectionPersister,
|
|
||||||
getInstance(),
|
|
||||||
persistenceContext.getEntry( getInstance() ),
|
|
||||||
getSession()
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
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 EntityPersister persister = getPersister();
|
||||||
final Object instance = getInstance();
|
final Object instance = getInstance();
|
||||||
persister.insert( id, getState(), instance, session );
|
persister.insert( id, getState(), instance, session );
|
||||||
PersistenceContext persistenceContext = session.getPersistenceContextInternal();
|
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
|
||||||
final EntityEntry entry = persistenceContext.getEntry( instance );
|
final EntityEntry entry = persistenceContext.getEntry( instance );
|
||||||
if ( entry == null ) {
|
if ( entry == null ) {
|
||||||
throw new AssertionFailure( "possible non-threadsafe access to session" );
|
throw new AssertionFailure( "possible non-threadsafe access to session" );
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.mapping;
|
package org.hibernate.metamodel.mapping;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
|
||||||
import org.hibernate.property.access.spi.PropertyAccess;
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
import org.hibernate.sql.results.graph.DatabaseSnapshotContributor;
|
import org.hibernate.sql.results.graph.DatabaseSnapshotContributor;
|
||||||
import org.hibernate.sql.results.graph.Fetchable;
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
|
@ -92,4 +93,30 @@ public interface AttributeMapping
|
||||||
return this;
|
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) {
|
SqlAstCreationState creationState) {
|
||||||
getCollectionDescriptor().applyWhereRestrictions( predicateConsumer, tableGroup, useQualifier, 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;
|
return parentInjectionAttributePropertyAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EmbeddedAttributeMapping asEmbeddedAttributeMapping() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmbeddedAttributeMapping() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue