HHH-15258 Orphan removal for OneToMany relations is broken when used with GenerationType.IDENTITY
This commit is contained in:
parent
1a94bcc4a2
commit
2af19a6278
|
@ -7,16 +7,22 @@
|
||||||
package org.hibernate.action.internal;
|
package org.hibernate.action.internal;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
|
import org.hibernate.collection.spi.PersistentCollection;
|
||||||
import org.hibernate.engine.internal.ForeignKeys;
|
import org.hibernate.engine.internal.ForeignKeys;
|
||||||
import org.hibernate.engine.internal.NonNullableTransientDependencies;
|
import org.hibernate.engine.internal.NonNullableTransientDependencies;
|
||||||
import org.hibernate.engine.internal.Nullability;
|
import org.hibernate.engine.internal.Nullability;
|
||||||
import org.hibernate.engine.internal.Versioning;
|
import org.hibernate.engine.internal.Versioning;
|
||||||
import org.hibernate.engine.spi.CachedNaturalIdValueSource;
|
import org.hibernate.engine.spi.CachedNaturalIdValueSource;
|
||||||
|
import org.hibernate.engine.spi.CollectionKey;
|
||||||
import org.hibernate.engine.spi.EntityEntry;
|
import org.hibernate.engine.spi.EntityEntry;
|
||||||
import org.hibernate.engine.spi.EntityKey;
|
import org.hibernate.engine.spi.EntityKey;
|
||||||
|
import org.hibernate.engine.spi.PersistenceContext;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.engine.spi.Status;
|
import org.hibernate.engine.spi.Status;
|
||||||
import org.hibernate.metamodel.mapping.NaturalIdMapping;
|
import org.hibernate.metamodel.mapping.NaturalIdMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.persister.entity.AbstractEntityPersister;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -132,6 +138,27 @@ public abstract class AbstractEntityInsertAction extends EntityAction {
|
||||||
getPersister(),
|
getPersister(),
|
||||||
isVersionIncrementDisabled
|
isVersionIncrementDisabled
|
||||||
);
|
);
|
||||||
|
if ( isEarlyInsert() ) {
|
||||||
|
final SharedSessionContractImplementor session = getSession();
|
||||||
|
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
|
||||||
|
Object[] objects = getState();
|
||||||
|
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()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
persistenceContext.addCollectionByKey( collectionKey, persistentCollection );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1614,7 +1614,7 @@ public abstract class AbstractEntityPersister
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Object getCollectionKey(
|
public Object getCollectionKey(
|
||||||
CollectionPersister persister,
|
CollectionPersister persister,
|
||||||
Object owner,
|
Object owner,
|
||||||
EntityEntry ownerEntry,
|
EntityEntry ownerEntry,
|
||||||
|
|
|
@ -6,16 +6,22 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.sql.results.graph.collection.internal;
|
package org.hibernate.sql.results.graph.collection.internal;
|
||||||
|
|
||||||
|
import org.hibernate.collection.spi.CollectionSemantics;
|
||||||
import org.hibernate.collection.spi.PersistentCollection;
|
import org.hibernate.collection.spi.PersistentCollection;
|
||||||
import org.hibernate.engine.spi.CollectionKey;
|
import org.hibernate.engine.spi.CollectionKey;
|
||||||
|
import org.hibernate.engine.spi.PersistenceContext;
|
||||||
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.internal.log.LoggingHelper;
|
import org.hibernate.internal.log.LoggingHelper;
|
||||||
|
import org.hibernate.metamodel.CollectionClassification;
|
||||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.persister.entity.AbstractEntityPersister;
|
import org.hibernate.persister.entity.AbstractEntityPersister;
|
||||||
import org.hibernate.spi.NavigablePath;
|
import org.hibernate.spi.NavigablePath;
|
||||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||||
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
|
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
|
||||||
import org.hibernate.sql.results.graph.collection.CollectionLoadingLogger;
|
import org.hibernate.sql.results.graph.collection.CollectionLoadingLogger;
|
||||||
|
import org.hibernate.sql.results.graph.collection.LoadingCollectionEntry;
|
||||||
import org.hibernate.sql.results.graph.entity.EntityInitializer;
|
import org.hibernate.sql.results.graph.entity.EntityInitializer;
|
||||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||||
|
|
||||||
|
@ -85,6 +91,56 @@ public abstract class AbstractCollectionInitializer implements CollectionInitial
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void resolveInstance(RowProcessingState rowProcessingState, boolean isEager) {
|
||||||
|
if ( collectionKey != null ) {
|
||||||
|
final SharedSessionContractImplementor session = rowProcessingState.getSession();
|
||||||
|
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
||||||
|
|
||||||
|
final LoadingCollectionEntry loadingEntry = persistenceContext.getLoadContexts()
|
||||||
|
.findLoadingCollectionEntry( collectionKey );
|
||||||
|
|
||||||
|
if ( loadingEntry != null ) {
|
||||||
|
collectionInstance = loadingEntry.getCollectionInstance();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final PersistentCollection<?> existing = persistenceContext.getCollection( collectionKey );
|
||||||
|
|
||||||
|
if ( existing != null ) {
|
||||||
|
collectionInstance = existing;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final CollectionPersister collectionDescriptor = collectionAttributeMapping.getCollectionDescriptor();
|
||||||
|
final CollectionSemantics<?, ?> collectionSemantics = collectionDescriptor.getCollectionSemantics();
|
||||||
|
final Object key = collectionKey.getKey();
|
||||||
|
|
||||||
|
collectionInstance = collectionSemantics.instantiateWrapper(
|
||||||
|
key,
|
||||||
|
collectionDescriptor,
|
||||||
|
session
|
||||||
|
);
|
||||||
|
|
||||||
|
parentAccess.registerResolutionListener(
|
||||||
|
owner -> collectionInstance.setOwner( owner )
|
||||||
|
);
|
||||||
|
|
||||||
|
persistenceContext.addUninitializedCollection(
|
||||||
|
collectionDescriptor,
|
||||||
|
collectionInstance,
|
||||||
|
key
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( isEager ) {
|
||||||
|
persistenceContext.addNonLazyCollection( collectionInstance );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( collectionSemantics.getCollectionClassification() == CollectionClassification.ARRAY ) {
|
||||||
|
session.getPersistenceContext().addCollectionHolder( collectionInstance );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean isAttributeAssignableToConcreteDescriptor() {
|
protected boolean isAttributeAssignableToConcreteDescriptor() {
|
||||||
if ( parentAccess instanceof EntityInitializer ) {
|
if ( parentAccess instanceof EntityInitializer ) {
|
||||||
final AbstractEntityPersister concreteDescriptor = (AbstractEntityPersister) ( (EntityInitializer) parentAccess ).getConcreteDescriptor();
|
final AbstractEntityPersister concreteDescriptor = (AbstractEntityPersister) ( (EntityInitializer) parentAccess ).getConcreteDescriptor();
|
||||||
|
|
|
@ -6,18 +6,11 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.sql.results.graph.collection.internal;
|
package org.hibernate.sql.results.graph.collection.internal;
|
||||||
|
|
||||||
import org.hibernate.collection.spi.CollectionSemantics;
|
|
||||||
import org.hibernate.collection.spi.PersistentCollection;
|
|
||||||
import org.hibernate.engine.spi.PersistenceContext;
|
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
|
||||||
import org.hibernate.internal.log.LoggingHelper;
|
import org.hibernate.internal.log.LoggingHelper;
|
||||||
import org.hibernate.metamodel.CollectionClassification;
|
|
||||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
|
||||||
import org.hibernate.spi.NavigablePath;
|
import org.hibernate.spi.NavigablePath;
|
||||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||||
import org.hibernate.sql.results.graph.collection.LoadingCollectionEntry;
|
|
||||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,49 +28,7 @@ public class DelayedCollectionInitializer extends AbstractCollectionInitializer
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resolveInstance(RowProcessingState rowProcessingState) {
|
public void resolveInstance(RowProcessingState rowProcessingState) {
|
||||||
if ( collectionKey != null ) {
|
resolveInstance( rowProcessingState, false );
|
||||||
final SharedSessionContractImplementor session = rowProcessingState.getSession();
|
|
||||||
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
|
||||||
|
|
||||||
final LoadingCollectionEntry loadingEntry = persistenceContext.getLoadContexts()
|
|
||||||
.findLoadingCollectionEntry( collectionKey );
|
|
||||||
|
|
||||||
if ( loadingEntry != null ) {
|
|
||||||
collectionInstance = loadingEntry.getCollectionInstance();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final PersistentCollection<?> existing = persistenceContext.getCollection( collectionKey );
|
|
||||||
|
|
||||||
if ( existing != null ) {
|
|
||||||
collectionInstance = existing;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final CollectionPersister collectionDescriptor = collectionAttributeMapping.getCollectionDescriptor();
|
|
||||||
final CollectionSemantics<?, ?> collectionSemantics = collectionDescriptor.getCollectionSemantics();
|
|
||||||
final Object key = collectionKey.getKey();
|
|
||||||
|
|
||||||
collectionInstance = collectionSemantics.instantiateWrapper(
|
|
||||||
key,
|
|
||||||
collectionDescriptor,
|
|
||||||
session
|
|
||||||
);
|
|
||||||
|
|
||||||
parentAccess.registerResolutionListener(
|
|
||||||
owner -> collectionInstance.setOwner( owner )
|
|
||||||
);
|
|
||||||
|
|
||||||
persistenceContext.addUninitializedCollection(
|
|
||||||
collectionDescriptor,
|
|
||||||
collectionInstance,
|
|
||||||
key
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( collectionSemantics.getCollectionClassification() == CollectionClassification.ARRAY ) {
|
|
||||||
session.getPersistenceContext().addCollectionHolder( collectionInstance );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -6,18 +6,11 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.sql.results.graph.collection.internal;
|
package org.hibernate.sql.results.graph.collection.internal;
|
||||||
|
|
||||||
import org.hibernate.collection.spi.CollectionSemantics;
|
|
||||||
import org.hibernate.collection.spi.PersistentCollection;
|
|
||||||
import org.hibernate.engine.spi.PersistenceContext;
|
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
|
||||||
import org.hibernate.internal.log.LoggingHelper;
|
import org.hibernate.internal.log.LoggingHelper;
|
||||||
import org.hibernate.metamodel.CollectionClassification;
|
|
||||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
|
||||||
import org.hibernate.spi.NavigablePath;
|
import org.hibernate.spi.NavigablePath;
|
||||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||||
import org.hibernate.sql.results.graph.collection.LoadingCollectionEntry;
|
|
||||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,51 +28,7 @@ public class SelectEagerCollectionInitializer extends AbstractCollectionInitiali
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resolveInstance(RowProcessingState rowProcessingState) {
|
public void resolveInstance(RowProcessingState rowProcessingState) {
|
||||||
if ( collectionKey != null ) {
|
resolveInstance( rowProcessingState, true );
|
||||||
final SharedSessionContractImplementor session = rowProcessingState.getSession();
|
|
||||||
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
|
||||||
|
|
||||||
final LoadingCollectionEntry loadingEntry = persistenceContext.getLoadContexts()
|
|
||||||
.findLoadingCollectionEntry( collectionKey );
|
|
||||||
|
|
||||||
if ( loadingEntry != null ) {
|
|
||||||
collectionInstance = loadingEntry.getCollectionInstance();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final PersistentCollection<?> existing = persistenceContext.getCollection( collectionKey );
|
|
||||||
|
|
||||||
if ( existing != null ) {
|
|
||||||
collectionInstance = existing;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final CollectionPersister collectionDescriptor = collectionAttributeMapping.getCollectionDescriptor();
|
|
||||||
final CollectionSemantics<?, ?> collectionSemantics = collectionDescriptor.getCollectionSemantics();
|
|
||||||
final Object key = collectionKey.getKey();
|
|
||||||
|
|
||||||
collectionInstance = collectionSemantics.instantiateWrapper(
|
|
||||||
key,
|
|
||||||
collectionDescriptor,
|
|
||||||
session
|
|
||||||
);
|
|
||||||
|
|
||||||
parentAccess.registerResolutionListener(
|
|
||||||
owner -> collectionInstance.setOwner( owner )
|
|
||||||
);
|
|
||||||
|
|
||||||
persistenceContext.addUninitializedCollection(
|
|
||||||
collectionDescriptor,
|
|
||||||
collectionInstance,
|
|
||||||
key
|
|
||||||
);
|
|
||||||
|
|
||||||
persistenceContext.addNonLazyCollection( collectionInstance );
|
|
||||||
|
|
||||||
if ( collectionSemantics.getCollectionClassification() == CollectionClassification.ARRAY ) {
|
|
||||||
session.getPersistenceContext().addCollectionHolder( collectionInstance );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue