Fix create a new instance while a corresponding one is loading
This commit is contained in:
parent
8dcd63dcee
commit
96f8273673
|
@ -480,15 +480,13 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
else {
|
||||
// look to see if another initializer from a parent load context or an earlier
|
||||
// initializer is already loading the entity
|
||||
if ( entityInstance == null ) {
|
||||
entityInstance = resolveInstance(
|
||||
entityIdentifier,
|
||||
rowProcessingState,
|
||||
session,
|
||||
persistenceContext
|
||||
);
|
||||
entityInstance = resolveInstance(
|
||||
entityIdentifier,
|
||||
rowProcessingState,
|
||||
session,
|
||||
persistenceContext
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ( LockMode.NONE != lockMode ) {
|
||||
|
@ -646,13 +644,16 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
if ( !hibernateLazyInitializer.isUninitialized() ) {
|
||||
return;
|
||||
}
|
||||
Object instance = resolveInstance(
|
||||
entityKey.getIdentifier(),
|
||||
rowProcessingState,
|
||||
session,
|
||||
persistenceContext
|
||||
);
|
||||
initializeEntity( instance, rowProcessingState, session, persistenceContext );
|
||||
Object instance = persistenceContext.getEntity( entityKey );
|
||||
if ( instance == null ) {
|
||||
instance = resolveInstance(
|
||||
entityKey.getIdentifier(),
|
||||
rowProcessingState,
|
||||
session,
|
||||
persistenceContext
|
||||
);
|
||||
initializeEntity( instance, rowProcessingState, session, persistenceContext );
|
||||
}
|
||||
hibernateLazyInitializer.setImplementation( instance );
|
||||
}
|
||||
else {
|
||||
|
@ -674,7 +675,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
|
||||
final Object entity = persistenceContext.getEntity( entityKey );
|
||||
assert entity == null || entity == toInitialize;
|
||||
//
|
||||
|
||||
// if ( entity != null ) {
|
||||
// return;
|
||||
// }
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.hibernate.loader.entity.CacheEntityLoaderHelper;
|
|||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.AbstractFetchParentAccess;
|
||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||
|
@ -78,51 +79,67 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
|
|||
final EntityKey entityKey = new EntityKey( identifier, concreteDescriptor );
|
||||
final PersistenceContext persistenceContext = rowProcessingState.getSession().getPersistenceContext();
|
||||
|
||||
final Object proxy = persistenceContext.getProxy( entityKey );
|
||||
if ( proxy != null ) {
|
||||
entityInstance = proxy;
|
||||
LoadingEntityEntry loadingEntityLocally = persistenceContext
|
||||
.getLoadContexts().findLoadingEntityEntry( entityKey );
|
||||
if ( loadingEntityLocally != null ) {
|
||||
entityInstance = loadingEntityLocally.getEntityInstance();
|
||||
}
|
||||
else {
|
||||
final Object entity = persistenceContext.getEntity( entityKey );
|
||||
if ( entity != null ) {
|
||||
final Object proxy = persistenceContext.getProxy( entityKey );
|
||||
if ( entity != null && proxy != null && ( (HibernateProxy) proxy ).getHibernateLazyInitializer()
|
||||
.isUninitialized() ) {
|
||||
entityInstance = entity;
|
||||
}
|
||||
else {
|
||||
LoadingEntityEntry loadingEntityLocally = rowProcessingState.getJdbcValuesSourceProcessingState()
|
||||
.findLoadingEntityLocally( entityKey );
|
||||
if ( loadingEntityLocally != null ) {
|
||||
entityInstance = loadingEntityLocally.getEntityInstance();
|
||||
if ( proxy != null ) {
|
||||
entityInstance = proxy;
|
||||
}
|
||||
else {
|
||||
// Look into the second level cache if the descriptor is polymorphic
|
||||
final Object cachedEntity;
|
||||
if ( concreteDescriptor.getEntityMetamodel().hasSubclasses() ) {
|
||||
cachedEntity = CacheEntityLoaderHelper.INSTANCE.loadFromSecondLevelCache(
|
||||
(EventSource) rowProcessingState.getSession(),
|
||||
null,
|
||||
LockMode.NONE,
|
||||
concreteDescriptor,
|
||||
entityKey
|
||||
);
|
||||
if ( entity != null ) {
|
||||
entityInstance = entity;
|
||||
}
|
||||
else {
|
||||
cachedEntity = null;
|
||||
}
|
||||
// Look into the second level cache if the descriptor is polymorphic
|
||||
final Object cachedEntity;
|
||||
if ( concreteDescriptor.getEntityMetamodel().hasSubclasses() ) {
|
||||
cachedEntity = CacheEntityLoaderHelper.INSTANCE.loadFromSecondLevelCache(
|
||||
(EventSource) rowProcessingState.getSession(),
|
||||
null,
|
||||
LockMode.NONE,
|
||||
concreteDescriptor,
|
||||
entityKey
|
||||
);
|
||||
}
|
||||
else {
|
||||
cachedEntity = null;
|
||||
}
|
||||
|
||||
if ( cachedEntity != null ) {
|
||||
entityInstance = cachedEntity;
|
||||
}
|
||||
else if ( concreteDescriptor.hasProxy() ) {
|
||||
entityInstance = concreteDescriptor.createProxy(
|
||||
identifier,
|
||||
rowProcessingState.getSession()
|
||||
);
|
||||
persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey( entityKey );
|
||||
persistenceContext.addProxy( entityKey, entityInstance );
|
||||
}
|
||||
else if ( concreteDescriptor.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading() ) {
|
||||
entityInstance = concreteDescriptor.getBytecodeEnhancementMetadata()
|
||||
.createEnhancedProxy( entityKey, true, rowProcessingState.getSession() );
|
||||
if ( cachedEntity != null ) {
|
||||
entityInstance = cachedEntity;
|
||||
}
|
||||
else {
|
||||
entityInstance = persistenceContext.getEntity( entityKey );
|
||||
if ( entityInstance == null ) {
|
||||
if ( concreteDescriptor.hasProxy() ) {
|
||||
entityInstance = concreteDescriptor.createProxy(
|
||||
identifier,
|
||||
rowProcessingState.getSession()
|
||||
);
|
||||
persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey( entityKey );
|
||||
persistenceContext.addProxy( entityKey, entityInstance );
|
||||
}
|
||||
else if ( concreteDescriptor.getBytecodeEnhancementMetadata()
|
||||
.isEnhancedForLazyLoading() ) {
|
||||
entityInstance = concreteDescriptor.getBytecodeEnhancementMetadata()
|
||||
.createEnhancedProxy(
|
||||
entityKey,
|
||||
true,
|
||||
rowProcessingState.getSession()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ package org.hibernate.sql.results.graph.entity.internal;
|
|||
import org.hibernate.engine.spi.EntityUniqueKey;
|
||||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.UniqueKeyLoadable;
|
||||
|
|
|
@ -126,7 +126,7 @@ public class DeleteMultiLevelOrphansTest extends BaseCoreFunctionalTestCase {
|
|||
results = session.createQuery( "from Preisregelung" ).list();
|
||||
assertEquals( 1, results.size() );
|
||||
Preisregelung preisregelung1Queried = (Preisregelung) results.get( 0 );
|
||||
assertEquals( tranchenmodellQueried, preisregelung1Queried.getTranchenmodell() );
|
||||
assertEquals( preisregelung1Queried.getTranchenmodell(), tranchenmodellQueried );
|
||||
results = session.createQuery( "from Tranche" ).list();
|
||||
assertEquals( 0, results.size() );
|
||||
|
||||
|
|
|
@ -14,13 +14,12 @@ import javax.persistence.OneToOne;
|
|||
|
||||
@Entity
|
||||
public class Preisregelung {
|
||||
@Id
|
||||
|
||||
private Long id;
|
||||
|
||||
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
|
||||
private Tranchenmodell tranchenmodell;
|
||||
|
||||
|
||||
@Id
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -29,6 +28,7 @@ public class Preisregelung {
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
|
||||
public Tranchenmodell getTranchenmodell() {
|
||||
return tranchenmodell;
|
||||
}
|
||||
|
|
|
@ -18,17 +18,16 @@ import javax.persistence.OneToOne;
|
|||
@Entity
|
||||
public class Tranchenmodell {
|
||||
|
||||
@Id
|
||||
|
||||
private Long id;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "tranchenmodell", fetch = FetchType.LAZY, orphanRemoval = true)
|
||||
private List<Tranche> tranchen = new ArrayList<Tranche>();
|
||||
|
||||
@OneToOne(mappedBy="tranchenmodell", optional = true, fetch = FetchType.LAZY)
|
||||
|
||||
private Preisregelung preisregelung;
|
||||
|
||||
|
||||
|
||||
@Id
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -37,10 +36,16 @@ public class Tranchenmodell {
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "tranchenmodell", fetch = FetchType.LAZY, orphanRemoval = true)
|
||||
public List<Tranche> getTranchen() {
|
||||
return tranchen;
|
||||
}
|
||||
|
||||
public void setTranchen(List<Tranche> tranchen) {
|
||||
this.tranchen = tranchen;
|
||||
}
|
||||
|
||||
@OneToOne(mappedBy="tranchenmodell", optional = true, fetch = FetchType.LAZY)
|
||||
public Preisregelung getPreisregelung() {
|
||||
return preisregelung;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue