mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-09 04:34:49 +00:00
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
efe5ee830d
commit
c30084010c
@ -18,10 +18,13 @@
|
|||||||
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 final void makeEntityManaged() {
|
|||||||
|
|
||||||
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 void execute() throws HibernateException {
|
|||||||
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 @@ default AttributeMapping asAttributeMapping() {
|
|||||||
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 @@ default void applyWhereRestrictions(
|
|||||||
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 @@ private static PropertyAccess getPropertyAccess(
|
|||||||
}
|
}
|
||||||
return parentInjectionAttributePropertyAccess;
|
return parentInjectionAttributePropertyAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EmbeddedAttributeMapping asEmbeddedAttributeMapping() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmbeddedAttributeMapping() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user