Re-enabled additional Inheritance related tests and fixed issues with initializer for subclasses

This commit is contained in:
Andrea Boriero 2020-07-02 17:58:36 +01:00
parent 923a7d8d07
commit 7470138e0f
32 changed files with 347 additions and 166 deletions

View File

@ -312,6 +312,7 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
.getFromClauseAccess()
.getTableGroup( fetchParent.getNavigablePath() );
return new CircularFetchImpl(
this,
getEntityMappingType(),
getTiming(),
fetchablePath,

View File

@ -55,12 +55,12 @@ public abstract class AbstractFetchParent implements FetchParent {
}
@Override
public Fetch findFetch(String fetchableName) {
public Fetch findFetch(Fetchable fetchable) {
if ( fetches != null ) {
for ( Fetch fetch : fetches ) {
final Fetchable fetchedMapping = fetch.getFetchedMapping();
if ( fetchedMapping != null && fetchedMapping
.getFetchableName().equals( fetchableName ) ) {
if ( fetchedMapping != null
&& fetchedMapping.getNavigableRole().equals( fetchable.getNavigableRole() ) ) {
return fetch;
}
}

View File

@ -8,6 +8,7 @@ package org.hibernate.sql.results.graph;
import java.util.function.Supplier;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
@ -15,6 +16,11 @@ import org.hibernate.sql.ast.spi.SqlAstCreationContext;
* @author Steve Ebersole
*/
public interface AssemblerCreationState {
Initializer resolveInitializer(NavigablePath navigablePath, Supplier<Initializer> producer);
Initializer resolveInitializer(
NavigablePath navigablePath,
ModelPart fetchedModelPart,
Supplier<Initializer> producer);
SqlAstCreationContext getSqlAstCreationContext();
}

View File

@ -63,5 +63,5 @@ public interface FetchParent extends DomainResultGraphNode {
*/
List<Fetch> getFetches();
Fetch findFetch(String fetchableName);
Fetch findFetch(Fetchable fetchable);
}

View File

@ -21,6 +21,7 @@ import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.FetchableContainer;
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
import org.hibernate.sql.results.graph.collection.CollectionResultGraphNode;
@ -81,6 +82,7 @@ public class CollectionDomainResult implements DomainResult, CollectionResultGra
public DomainResultAssembler createResultAssembler(AssemblerCreationState creationState) {
final CollectionInitializer initializer = (CollectionInitializer) creationState.resolveInitializer(
getNavigablePath(),
getReferencedModePart(),
() -> {
final DomainResultAssembler fkAssembler = fkResult.createResultAssembler( creationState );
@ -120,7 +122,7 @@ public class CollectionDomainResult implements DomainResult, CollectionResultGra
}
@Override
public Fetch findFetch(String fetchableName) {
public Fetch findFetch(Fetchable fetchable) {
return null;
}

View File

@ -28,6 +28,7 @@ public class DelayedCollectionAssembler extends AbstractCollectionAssembler {
fetchedMapping,
() -> (CollectionInitializer) creationState.resolveInitializer(
fetchPath,
fetchedMapping,
() -> new DelayedCollectionInitializer( fetchPath, fetchedMapping, parentAccess )
)

View File

@ -25,6 +25,7 @@ import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.FetchableContainer;
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
@ -108,6 +109,7 @@ public class EagerCollectionFetch extends CollectionFetch implements FetchParent
public DomainResultAssembler createAssembler(FetchParentAccess parentAccess, AssemblerCreationState creationState) {
final CollectionInitializer initializer = (CollectionInitializer) creationState.resolveInitializer(
getNavigablePath(),
getReferencedModePart(),
() -> {
final DomainResultAssembler keyContainerAssembler = keyContainerResult.createResultAssembler( creationState );
@ -160,17 +162,17 @@ public class EagerCollectionFetch extends CollectionFetch implements FetchParent
}
@Override
public Fetch findFetch(String fetchableName) {
if ( CollectionPart.Nature.ELEMENT.getName().equals( fetchableName ) ) {
public Fetch findFetch(Fetchable fetchable) {
if ( CollectionPart.Nature.ELEMENT.getName().equals( fetchable.getFetchableName() ) ) {
return elementFetch;
}
else if ( CollectionPart.Nature.INDEX.getName().equals( fetchableName ) ) {
else if ( CollectionPart.Nature.INDEX.getName().equals( fetchable.getFetchableName() ) ) {
return indexFetch;
}
else {
throw new IllegalArgumentException(
"Unknown fetchable [" + getFetchedMapping().getCollectionDescriptor().getRole() +
" -> " + fetchableName + "]"
" -> " + fetchable.getFetchableName() + "]"
);
}
}

View File

@ -26,6 +26,7 @@ public class SelectEagerCollectionAssembler extends AbstractCollectionAssembler
fetchedMapping,
() -> (CollectionInitializer) creationState.resolveInitializer(
fetchPath,
fetchedMapping,
() -> new SelectEagerCollectionInitializer( fetchPath, fetchedMapping, parentAccess )
)
);

View File

@ -55,7 +55,7 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
embeddableTypeDescriptor.visitStateArrayContributors(
stateArrayContributor -> {
final Fetch fetch = resultDescriptor.findFetch( stateArrayContributor.getFetchableName() );
final Fetch fetch = resultDescriptor.findFetch( stateArrayContributor );
final DomainResultAssembler stateAssembler = fetch == null
? new NullValueAssembler( stateArrayContributor.getJavaTypeDescriptor() )

View File

@ -113,6 +113,7 @@ public class EmbeddableFetchImpl extends AbstractFetchParent implements Embeddab
AssemblerCreationState creationState) {
final EmbeddableInitializer initializer = (EmbeddableInitializer) creationState.resolveInitializer(
getNavigablePath(),
getReferencedModePart(),
() -> new EmbeddableFetchInitializer(
parentAccess,
this,

View File

@ -39,6 +39,7 @@ public class EmbeddableForeignKeyResultImpl<T>
extends AbstractFetchParent
implements EmbeddableResultGraphNode, DomainResult<T> {
private static final String ROLE_LOCAL_NAME = "{fk}";
private final String resultVariable;
public EmbeddableForeignKeyResultImpl(
@ -47,15 +48,15 @@ public class EmbeddableForeignKeyResultImpl<T>
EmbeddableValuedModelPart embeddableValuedModelPart,
String resultVariable,
DomainResultCreationState creationState) {
super( embeddableValuedModelPart.getEmbeddableTypeDescriptor(), navigablePath );
super( embeddableValuedModelPart.getEmbeddableTypeDescriptor(), navigablePath.append( ROLE_LOCAL_NAME ) );
this.resultVariable = resultVariable;
fetches = new ArrayList<>();
MutableInteger index = new MutableInteger();
embeddableValuedModelPart.visitFetchables(
fetchable -> {
generateFetches( sqlSelections, navigablePath, creationState, index, fetchable );
},
fetchable ->
generateFetches( sqlSelections, navigablePath, creationState, index, fetchable )
,
null
);
}
@ -120,6 +121,7 @@ public class EmbeddableForeignKeyResultImpl<T>
public DomainResultAssembler<T> createResultAssembler(AssemblerCreationState creationState) {
final EmbeddableInitializer initializer = (EmbeddableInitializer) creationState.resolveInitializer(
getNavigablePath(),
getReferencedModePart(),
() -> new EmbeddableResultInitializer(this, creationState )
);
@ -127,19 +129,14 @@ public class EmbeddableForeignKeyResultImpl<T>
return new EmbeddableAssembler( initializer );
}
@Override
public NavigablePath getNavigablePath() {
return super.getNavigablePath().append( "{fk}");
}
@Override
public EmbeddableMappingType getReferencedMappingType() {
return (EmbeddableMappingType) getFetchContainer().getPartMappingType();
}
@Override
public Fetch findFetch(String fetchableName) {
return super.findFetch( fetchableName );
public Fetch findFetch(Fetchable fetchable) {
return super.findFetch( fetchable );
}
@Override

View File

@ -87,6 +87,7 @@ public class EmbeddableResultImpl<T> extends AbstractFetchParent implements Embe
public DomainResultAssembler<T> createResultAssembler(AssemblerCreationState creationState) {
final EmbeddableInitializer initializer = (EmbeddableInitializer) creationState.resolveInitializer(
getNavigablePath(),
getReferencedModePart(),
() -> new EmbeddableResultInitializer(
this,
creationState

View File

@ -34,6 +34,8 @@ import org.hibernate.event.spi.PreLoadEvent;
import org.hibernate.event.spi.PreLoadEventListener;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Loadable;
import org.hibernate.proxy.HibernateProxy;
@ -67,6 +69,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
private final EntityPersister entityDescriptor;
private final EntityPersister rootEntityDescriptor;
private EntityPersister concreteDescriptor;
private final NavigablePath navigablePath;
private final LockMode lockMode;
@ -80,7 +83,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
private final Map<AttributeMapping, DomainResultAssembler> assemblerMap;
// per-row state
private EntityPersister concreteDescriptor;
private final EntityValuedModelPart referencedModelPart;
private EntityKey entityKey;
private Object entityInstance;
private boolean missing;
@ -100,7 +103,8 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
AssemblerCreationState creationState) {
super( );
this.entityDescriptor = (EntityPersister) resultDescriptor.getEntityValuedModelPart().getEntityMappingType();
this.referencedModelPart = resultDescriptor.getEntityValuedModelPart();
this.entityDescriptor = (EntityPersister) referencedModelPart.getEntityMappingType();
final String rootEntityName = entityDescriptor.getRootEntityName();
if ( rootEntityName == null || rootEntityName.equals( entityDescriptor.getEntityName() ) ) {
@ -117,10 +121,15 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
this.identifierAssembler = identifierResult.createResultAssembler(
new AssemblerCreationState() {
@Override
public Initializer resolveInitializer(NavigablePath navigablePath, Supplier<Initializer> producer) {
public Initializer resolveInitializer(
NavigablePath navigablePath,
ModelPart fetchedModelPart,
Supplier<Initializer> producer) {
for ( int i = 0; i < identifierInitializers.size(); i++ ) {
final Initializer existing = identifierInitializers.get( i );
if ( existing.getNavigablePath().equals( navigablePath ) ) {
if ( existing.getNavigablePath().equals( navigablePath )
&& fetchedModelPart.getNavigableRole().equals(
existing.getInitializedPart().getNavigableRole() ) ) {
return existing;
}
}
@ -185,7 +194,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
// note that lazy proxies or uninitialized collections count against
// that in the affirmative
final Fetch fetch = resultDescriptor.findFetch( fetchable.getFetchableName() );
final Fetch fetch = resultDescriptor.findFetch( fetchable );
final DomainResultAssembler stateAssembler;
if ( fetch == null ) {
@ -201,6 +210,11 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
);
}
@Override
public ModelPart getInitializedPart(){
return referencedModelPart;
}
protected abstract String getSimpleConcreteImplName();
public NavigablePath getNavigablePath() {
@ -268,6 +282,10 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
final SharedSessionContractImplementor session = rowProcessingState.getJdbcValuesSourceProcessingState().getSession();
concreteDescriptor = determineConcreteEntityDescriptor( rowProcessingState, session );
if ( concreteDescriptor == null ) {
missing = true;
return;
}
initializeIdentifier( rowProcessingState );
resolveEntityKey( rowProcessingState );
@ -306,21 +324,22 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
rowProcessingState.getJdbcValuesSourceProcessingState().getProcessingOptions()
);
final String concreteEntityName = ( (Loadable) rootEntityDescriptor ).getSubclassForDiscriminatorValue( discriminatorValue );
final String concreteEntityName = ( (Loadable) entityDescriptor ).getSubclassForDiscriminatorValue( discriminatorValue );
if ( concreteEntityName == null ) {
// oops - we got an instance of another class hierarchy branch
throw new WrongClassException(
"Discriminator: " + discriminatorValue,
entityKey.getIdentifier(),
entityDescriptor.getEntityName()
);
// throw new WrongClassException(
// "Discriminator: " + discriminatorValue,
// entityKey.getIdentifier(),
// entityDescriptor.getEntityName()
// );
return null;
}
final EntityPersister concreteType = session.getFactory().getMetamodel().findEntityDescriptor( concreteEntityName );
// verify that the `entityDescriptor` is either == concreteType or its super-type
assert concreteType.isTypeOrSuperType( rootEntityDescriptor );
assert concreteType.isTypeOrSuperType( entityDescriptor );
return concreteType;
}

View File

@ -19,10 +19,6 @@ import org.hibernate.persister.entity.EntityPersister;
* @author Steve Ebersole
*/
public interface EntityInitializer extends Initializer, FetchParentAccess {
@Override
default ModelPart getInitializedPart() {
return getEntityDescriptor();
}
/**
* Get the descriptor for the type of entity being initialized

View File

@ -13,6 +13,7 @@ import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.entity.EntityFetch;
import org.hibernate.sql.results.graph.entity.EntityValuedFetchable;
@ -59,7 +60,7 @@ public abstract class AbstractNonJoinedEntityFetch implements EntityFetch {
}
@Override
public Fetch findFetch(String fetchableName) {
public Fetch findFetch(Fetchable fetchable) {
return null;
}

View File

@ -47,11 +47,13 @@ public class EntityDelayedFetchImpl extends AbstractNonJoinedEntityFetch {
public DomainResultAssembler createAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
final NavigablePath navigablePath = getNavigablePath();
final EntityInitializer entityInitializer = (EntityInitializer) creationState.resolveInitializer(
getNavigablePath(),
navigablePath,
getEntityValuedModelPart(),
() -> new EntityDelayedFetchInitializer(
getNavigablePath(),
getEntityValuedModelPart().getEntityMappingType().getEntityPersister(),
navigablePath,
getEntityValuedModelPart(),
keyResult.createResultAssembler( creationState )
)
);

View File

@ -12,6 +12,8 @@ import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.internal.log.LoggingHelper;
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.results.graph.AbstractFetchParentAccess;
@ -27,7 +29,7 @@ import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess implements EntityInitializer {
private final NavigablePath navigablePath;
private final EntityPersister concreteDescriptor;
private final EntityValuedModelPart referencedModelPart;
private final DomainResultAssembler identifierAssembler;
private Object entityInstance;
@ -35,10 +37,10 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
public EntityDelayedFetchInitializer(
NavigablePath fetchedNavigable,
EntityPersister concreteDescriptor,
EntityValuedModelPart referencedModelPart,
DomainResultAssembler identifierAssembler) {
this.navigablePath = fetchedNavigable;
this.concreteDescriptor = concreteDescriptor;
this.referencedModelPart = referencedModelPart;
this.identifierAssembler = identifierAssembler;
}
@ -52,6 +54,11 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
// nothing to do
}
@Override
public ModelPart getInitializedPart(){
return referencedModelPart;
}
@Override
public void resolveInstance(RowProcessingState rowProcessingState) {
if ( entityInstance != null ) {
@ -64,6 +71,8 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
entityInstance = null;
}
else {
final EntityPersister concreteDescriptor = referencedModelPart.getEntityMappingType().getEntityPersister();
final EntityKey entityKey = new EntityKey( identifier, concreteDescriptor );
PersistenceContext persistenceContext = rowProcessingState.getSession().getPersistenceContext();
final Object entity = persistenceContext.getEntity( entityKey );
@ -120,7 +129,7 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
@Override
public EntityPersister getEntityDescriptor() {
return concreteDescriptor;
return referencedModelPart.getEntityMappingType().getEntityPersister();
}
@Override

View File

@ -8,6 +8,7 @@ package org.hibernate.sql.results.graph.entity.internal;
import org.hibernate.LockMode;
import org.hibernate.engine.FetchTiming;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.results.graph.AssemblerCreationState;
import org.hibernate.sql.results.graph.DomainResultCreationState;
@ -49,6 +50,7 @@ public class EntityFetchJoinedImpl extends AbstractNonLazyEntityFetch {
AssemblerCreationState creationState) {
return (EntityInitializer) creationState.resolveInitializer(
getNavigablePath(),
getEntityValuedModelPart(),
() -> new EntityJoinedFetchInitializer(
entityResult,
getNavigablePath(),

View File

@ -56,12 +56,14 @@ public class EntityFetchSelectImpl extends AbstractNonJoinedEntityFetch {
public DomainResultAssembler createAssembler(FetchParentAccess parentAccess, AssemblerCreationState creationState) {
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
getNavigablePath(),
getFetchedMapping(),
() -> {
EntityPersister entityPersister = getReferencedMappingContainer().getEntityPersister();
if ( selectByUniqueKey ) {
return new EntitySelectFetchByUniqueKeyInitializer(
getFetchedMapping(),
(ToOneAttributeMapping) getFetchedMapping(),
getNavigablePath(),
entityPersister,
@ -70,6 +72,7 @@ public class EntityFetchSelectImpl extends AbstractNonJoinedEntityFetch {
);
}
return new EntitySelectFetchInitializer(
getFetchedMapping(),
getNavigablePath(),
entityPersister,
result.createResultAssembler( creationState ),

View File

@ -70,6 +70,7 @@ public class EntityResultImpl extends AbstractEntityResultGraphNode implements E
public DomainResultAssembler createResultAssembler(AssemblerCreationState creationState) {
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
getNavigablePath(),
getReferencedModePart(),
() -> new EntityResultInitializer(
this,
getNavigablePath(),

View File

@ -33,6 +33,7 @@ public class EntityResultJoinedSubclassImpl extends EntityResultImpl {
public DomainResultAssembler createResultAssembler(AssemblerCreationState creationState) {
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
getNavigablePath(),
getReferencedModePart(),
() -> new EntityResultInitializer(
this,
getNavigablePath(),

View File

@ -9,6 +9,7 @@ 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;
@ -23,12 +24,13 @@ public class EntitySelectFetchByUniqueKeyInitializer extends EntitySelectFetchIn
private final ToOneAttributeMapping fetchedAttribute;
public EntitySelectFetchByUniqueKeyInitializer(
EntityValuedModelPart referencedModelPart,
ToOneAttributeMapping fetchedAttribute,
NavigablePath fetchedNavigable,
EntityPersister concreteDescriptor,
DomainResultAssembler identifierAssembler,
boolean nullable) {
super( fetchedNavigable, concreteDescriptor, identifierAssembler, nullable );
super( referencedModelPart, fetchedNavigable, concreteDescriptor, identifierAssembler, nullable );
this.fetchedAttribute = fetchedAttribute;
}

View File

@ -14,6 +14,8 @@ import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.log.LoggingHelper;
import org.hibernate.internal.util.StringHelper;
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;
@ -22,6 +24,7 @@ import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.Initializer;
import org.hibernate.sql.results.graph.entity.EntityInitializer;
import org.hibernate.sql.results.graph.entity.EntityLoadingLogger;
import org.hibernate.sql.results.graph.entity.EntityResultGraphNode;
import org.hibernate.sql.results.graph.entity.EntityValuedFetchable;
import org.hibernate.sql.results.graph.entity.LoadingEntityEntry;
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
@ -40,9 +43,12 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
protected final EntityPersister concreteDescriptor;
protected final DomainResultAssembler identifierAssembler;
private final EntityValuedModelPart referencedModelPart;
protected Object entityInstance;
public EntitySelectFetchInitializer(
EntityValuedModelPart referencedModelPart,
NavigablePath fetchedNavigable,
EntityPersister concreteDescriptor,
DomainResultAssembler identifierAssembler,
@ -51,9 +57,14 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
this.concreteDescriptor = concreteDescriptor;
this.identifierAssembler = identifierAssembler;
this.nullable = nullable;
this.referencedModelPart = referencedModelPart;
this.isEnhancedForLazyLoading = concreteDescriptor.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading();
}
public ModelPart getInitializedPart(){
return referencedModelPart;
}
@Override
public NavigablePath getNavigablePath() {
return navigablePath;

View File

@ -17,6 +17,7 @@ import org.hibernate.engine.spi.BatchFetchQueue;
import org.hibernate.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
@ -44,17 +45,22 @@ public class ResultsHelper {
//noinspection rawtypes
final List<DomainResultAssembler> assemblers = jdbcValues.getValuesMapping().resolveAssemblers(
new AssemblerCreationState() {
@Override
public Initializer resolveInitializer(
NavigablePath navigablePath,
ModelPart fetchedModelPart,
Supplier<Initializer> producer) {
final Initializer existing = initializerMap.get( navigablePath );
if ( existing != null ) {
ResultsLogger.LOGGER.debugf(
"Returning previously-registered initializer : %s",
existing
);
return existing;
if ( fetchedModelPart.getNavigableRole().equals(
existing.getInitializedPart().getNavigableRole() ) ) {
ResultsLogger.LOGGER.debugf(
"Returning previously-registered initializer : %s",
existing
);
return existing;
}
}
final Initializer initializer = producer.get();

View File

@ -11,6 +11,7 @@ import org.hibernate.engine.FetchTiming;
import org.hibernate.metamodel.mapping.Association;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
import org.hibernate.metamodel.mapping.MappingType;
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
@ -39,6 +40,7 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
*/
public class CircularFetchImpl implements BiDirectionalFetch, Association {
private DomainResult keyResult;
private EntityValuedModelPart referencedModelPart;
private final EntityMappingType entityMappingType;
private final FetchTiming timing;
private final NavigablePath navigablePath;
@ -48,6 +50,7 @@ public class CircularFetchImpl implements BiDirectionalFetch, Association {
private final NavigablePath referencedNavigablePath;
public CircularFetchImpl(
EntityValuedModelPart referencedModelPart,
EntityMappingType entityMappingType,
FetchTiming timing,
NavigablePath navigablePath,
@ -55,6 +58,7 @@ public class CircularFetchImpl implements BiDirectionalFetch, Association {
ToOneAttributeMapping fetchable,
NavigablePath referencedNavigablePath,
DomainResult keyResult) {
this.referencedModelPart = referencedModelPart;
this.entityMappingType = entityMappingType;
this.timing = timing;
this.fetchParent = fetchParent;
@ -98,9 +102,11 @@ public class CircularFetchImpl implements BiDirectionalFetch, Association {
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
getNavigablePath(),
referencedModelPart,
() -> {
if ( timing == FetchTiming.IMMEDIATE ) {
return new EntitySelectFetchInitializer(
referencedModelPart,
getReferencedPath(),
entityMappingType.getEntityPersister(),
resultAssembler,
@ -110,7 +116,7 @@ public class CircularFetchImpl implements BiDirectionalFetch, Association {
else {
return new EntityDelayedFetchInitializer(
getReferencedPath(),
(EntityPersister) ( (AttributeMapping) fetchable ).getMappedTypeDescriptor(),
fetchable,
resultAssembler
);
}

View File

@ -6,7 +6,9 @@
*/
package org.hibernate.orm.test.entitygraph.ast;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
@ -27,9 +29,11 @@ import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.graph.GraphSemantic;
import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.hql.spi.HqlQueryImplementor;
import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.query.sqm.internal.QuerySqmImpl;
@ -44,6 +48,7 @@ import org.hibernate.sql.ast.tree.from.TableGroupJoin;
import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.collection.internal.DelayedCollectionFetch;
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
import org.hibernate.sql.results.graph.entity.EntityFetch;
@ -183,8 +188,10 @@ public class CriteriaEntityGraphTest implements SessionFactoryScopeAware {
expectedFetchClassByAttributeName.put( "pets", DelayedCollectionFetch.class );
expectedFetchClassByAttributeName.put( "company", EntityFetchJoinedImpl.class );
assertThat( fetchClassByAttributeName, is( expectedFetchClassByAttributeName ) );
Fetchable fetchable = getFetchable( "company", Person.class );
final Fetch companyFetch = ownerEntityResult.findFetch( "company" );
final Fetch companyFetch = ownerEntityResult.findFetch( fetchable );
List<Fetch> fetches = ownerEntityResult.getFetches();
assertThat( companyFetch, notNullValue() );
final EntityResult companyEntityResult = ( (EntityFetchJoinedImpl) companyFetch).getEntityResult();
@ -198,6 +205,19 @@ public class CriteriaEntityGraphTest implements SessionFactoryScopeAware {
);
}
private Fetchable getFetchable(String attributeName, Class entityClass) {
EntityPersister person = scope.getSessionFactory().getDomainModel().findEntityDescriptor(
entityClass.getName() );
Collection<AttributeMapping> attributeMappings = person.getAttributeMappings();
Fetchable fetchable = null;
for(AttributeMapping mapping :attributeMappings){
if(mapping.getAttributeName().equals( attributeName )){
fetchable = (Fetchable) mapping;
}
}
return fetchable;
}
@ParameterizedTest
@EnumSource( GraphSemantic.class )
void testBasicElementCollections(GraphSemantic graphSemantic) {

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.orm.test.entitygraph.ast;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@ -26,6 +27,7 @@ import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.graph.GraphSemantic;
import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.loader.ast.internal.LoaderSelectBuilder;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
@ -38,6 +40,7 @@ import org.hibernate.sql.ast.tree.from.TableGroupJoin;
import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.collection.internal.DelayedCollectionFetch;
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
import org.hibernate.sql.results.graph.entity.EntityFetch;
@ -180,7 +183,8 @@ public class EntityGraphLoadPlanBuilderTest implements SessionFactoryScopeAware
expectedFetchClassByAttributeName.put( "company", EntityFetchJoinedImpl.class );
assertThat( fetchClassByAttributeName, is( expectedFetchClassByAttributeName ) );
final Fetch companyFetch = ownerEntityResult.findFetch( "company" );
Fetchable fetchable = getFetchable( "company", Person.class );
final Fetch companyFetch = ownerEntityResult.findFetch( fetchable );
assertThat( companyFetch, notNullValue() );
final EntityResult companyEntityResult = ( (EntityFetchJoinedImpl) companyFetch).getEntityResult();
@ -194,6 +198,19 @@ public class EntityGraphLoadPlanBuilderTest implements SessionFactoryScopeAware
);
}
private Fetchable getFetchable(String attributeName, Class entityClass) {
EntityPersister person = scope.getSessionFactory().getDomainModel().findEntityDescriptor(
entityClass.getName() );
Collection<AttributeMapping> attributeMappings = person.getAttributeMappings();
Fetchable fetchable = null;
for(AttributeMapping mapping :attributeMappings){
if(mapping.getAttributeName().equals( attributeName )){
fetchable = (Fetchable) mapping;
}
}
return fetchable;
}
@ParameterizedTest
@EnumSource( GraphSemantic.class )
void testBasicElementCollections(GraphSemantic graphSemantic) {

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.orm.test.entitygraph.ast;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@ -24,9 +25,11 @@ import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.graph.GraphSemantic;
import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.hql.spi.HqlQueryImplementor;
import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.query.sqm.internal.QuerySqmImpl;
@ -41,6 +44,7 @@ import org.hibernate.sql.ast.tree.from.TableGroupJoin;
import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.collection.internal.DelayedCollectionFetch;
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
import org.hibernate.sql.results.graph.entity.EntityFetch;
@ -181,7 +185,8 @@ public class HqlEntityGraphTest implements SessionFactoryScopeAware {
expectedFetchClassByAttributeName.put( "company", EntityFetchJoinedImpl.class );
assertThat( fetchClassByAttributeName, is( expectedFetchClassByAttributeName ) );
final Fetch companyFetch = ownerEntityResult.findFetch( "company" );
Fetchable fetchable = getFetchable( "company", Person.class );
final Fetch companyFetch = ownerEntityResult.findFetch( fetchable );
assertThat( companyFetch, notNullValue() );
final EntityResult companyEntityResult = ( (EntityFetchJoinedImpl) companyFetch).getEntityResult();
@ -195,6 +200,19 @@ public class HqlEntityGraphTest implements SessionFactoryScopeAware {
);
}
private Fetchable getFetchable(String attributeName, Class entityClass) {
EntityPersister person = scope.getSessionFactory().getDomainModel().findEntityDescriptor(
entityClass.getName() );
Collection<AttributeMapping> attributeMappings = person.getAttributeMappings();
Fetchable fetchable = null;
for(AttributeMapping mapping :attributeMappings){
if(mapping.getAttributeName().equals( attributeName )){
fetchable = (Fetchable) mapping;
}
}
return fetchable;
}
@ParameterizedTest
@EnumSource( GraphSemantic.class )
void testBasicElementCollections(GraphSemantic graphSemantic) {

View File

@ -10,6 +10,7 @@ import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
@ -17,6 +18,8 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.Hibernate;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
@ -25,6 +28,7 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ -49,8 +53,8 @@ public class MultiSingleTableLoadTest {
@BeforeEach
public void createTestData(SessionFactoryScope scope) {
scope.inTransaction( session -> {
Holder holder1 = new Holder( 1, new B( 1, new Y( 1 ) ) );
Holder holder2 = new Holder( 2, new C( 2, new Z( 2 ) ) );
Holder holder1 = new Holder( 1, new B( 1, new Y( 1, "y" ) ) );
Holder holder2 = new Holder( 2, new C( 2, new Z( 2, "z" ) ) );
session.persist( holder1 );
session.persist( holder2 );
@ -76,7 +80,22 @@ public class MultiSingleTableLoadTest {
Holder task1 = session.find( Holder.class, 1L );
Holder task2 = session.find( Holder.class, 2L );
assertNotNull( task1 );
A task1A = task1.getA();
assertTrue( task1A instanceof B );
B b = (B) task1A;
assertTrue( b.getX() instanceof Y );
assertTrue( Hibernate.isInitialized( b.getX() ) );
assertEquals( "y", b.getX().getTheString() );
assertNotNull( task2 );
A task2A = task2.getA();
assertTrue( task2A instanceof C );
C c = (C) task2A;
assertTrue( c.getX() instanceof Z );
assertTrue( Hibernate.isInitialized( c.getX() ) );
Z z = (Z) c.getX();
assertEquals( "z", z.getTheString() );
} );
}
@ -111,6 +130,10 @@ public class MultiSingleTableLoadTest {
this.id = id;
this.a = a;
}
public A getA() {
return a;
}
}
@Entity(name = "A")
@ -131,7 +154,7 @@ public class MultiSingleTableLoadTest {
@Entity(name = "B")
@DiscriminatorValue("B")
public static class B extends A {
@ManyToOne(optional = true, cascade = CascadeType.ALL)
@ManyToOne(optional = true, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "x_id")
private Y x;
@ -142,6 +165,10 @@ public class MultiSingleTableLoadTest {
super( id );
this.x = x;
}
public Y getX() {
return x;
}
}
@Entity(name = "C")
@ -158,6 +185,10 @@ public class MultiSingleTableLoadTest {
super( id );
this.x = x;
}
public X getX() {
return x;
}
}
@Entity(name = "X")
@ -178,22 +209,36 @@ public class MultiSingleTableLoadTest {
@Entity(name = "Y")
@DiscriminatorValue("Y")
public static class Y extends X {
private String theString;
public Y() {
}
public Y(long id) {
public Y(long id, String theString) {
super( id );
this.theString = theString;
}
public String getTheString() {
return theString;
}
}
@Entity(name = "Z")
@DiscriminatorValue("Z")
public static class Z extends X {
private String theString;
public Z() {
}
public Z(long id) {
public Z(long id, String theString) {
super( id );
this.theString = theString;
}
public String getTheString() {
return theString;
}
}
}

View File

@ -0,0 +1,53 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.orm.test.inheritance.discriminator;
import org.hibernate.Session;
import org.hibernate.dialect.PostgreSQL81Dialect;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.RequiresDialect;
import org.hibernate.testing.orm.junit.RequiresDialects;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.test.inheritance.discriminator.InheritingEntity;
import org.hibernate.test.inheritance.discriminator.ParentEntity;
import org.junit.jupiter.api.Test;
/**
* @author Pawel Stawicki
*/
@RequiresDialects(value = {
@RequiresDialect(value = PostgreSQL81Dialect.class), @RequiresDialect(value = PostgreSQLDialect.class)
})
@DomainModel(annotatedClasses = {
ParentEntity.class, InheritingEntity.class
})
@TestForIssue(jiraKey = "HHH-6580")
public class PersistChildEntitiesWithDiscriminatorTest {
@Test
public void doIt(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
// we need the 2 inserts so that the id is incremented on the second get-generated-keys-result set, since
// on the first insert both the pk and the discriminator values are 1
session.save( new InheritingEntity( "yabba" ) );
session.save( new InheritingEntity( "dabba" ) );
}
);
scope.inTransaction(
session -> {
session.createQuery( "delete ParentEntity" ).executeUpdate();
}
);
}
}

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.inheritance.discriminator;
package org.hibernate.orm.test.inheritance.discriminator;
import java.util.ArrayList;
import java.util.Arrays;
@ -22,20 +22,31 @@ import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Before;
import org.junit.Test;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.junit.jupiter.api.Assertions.fail;
/**
* @author Davide D'Alto
*/
@TestForIssue( jiraKey = "HHH-12332")
public class SingleTableInheritancePersistTest extends BaseCoreFunctionalTestCase {
@TestForIssue(jiraKey = "HHH-12332")
@DomainModel(
annotatedClasses = {
SingleTableInheritancePersistTest.Family.class,
SingleTableInheritancePersistTest.Person.class,
SingleTableInheritancePersistTest.Child.class,
SingleTableInheritancePersistTest.Man.class,
SingleTableInheritancePersistTest.Woman.class
}
)
@SessionFactory
public class SingleTableInheritancePersistTest {
private final Man john = new Man( "John", "Riding Roller Coasters" );
private final Woman jane = new Woman( "Jane", "Hippotherapist" );
@ -45,66 +56,57 @@ public class SingleTableInheritancePersistTest extends BaseCoreFunctionalTestCas
private final List<Child> children = new ArrayList<>( Arrays.asList( susan, mark ) );
private final List<Person> familyMembers = Arrays.asList( john, jane, susan, mark );
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] {
Family.class,
Person.class,
Child.class,
Man.class,
Woman.class
};
}
@BeforeEach
public void setUp(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
jane.setHusband( john );
jane.setChildren( children );
@Before
public void setUp() {
doInHibernate( this::sessionFactory, session -> {
jane.setHusband( john );
jane.setChildren( children );
john.setWife( jane );
john.setChildren( children );
john.setWife( jane );
john.setChildren( children );
for ( Child child : children ) {
child.setFather( john );
child.setMother( jane );
}
for ( Child child : children ) {
child.setFather( john );
child.setMother( jane );
}
for ( Person person : familyMembers ) {
family.add( person );
}
for ( Person person : familyMembers ) {
family.add( person );
}
session.persist( family );
} );
session.persist( family );
} );
}
@Test
public void testPolymorphicAssociation() {
doInHibernate( this::sessionFactory, session1 -> {
Family family = session1.createQuery( "FROM Family f", Family.class ).getSingleResult();
List<Person> members = family.getMembers();
assertThat( members.size(), is( familyMembers.size() ) );
for ( Person person : members ) {
if ( person instanceof Man ) {
assertThat( ( (Man) person ).getHobby(), is( john.getHobby() ) );
}
else if ( person instanceof Woman ) {
assertThat( ( (Woman) person ).getJob(), is( jane.getJob() ) );
}
else if ( person instanceof Child ) {
if ( person.getName().equals( "Susan" ) ) {
assertThat( ( (Child) person ).getFavouriteToy(), is( susan.getFavouriteToy() ) );
public void testPolymorphicAssociation(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
Family family = session.createQuery( "FROM Family f", Family.class ).getSingleResult();
List<Person> members = family.getMembers();
assertThat( members.size(), is( familyMembers.size() ) );
for ( Person person : members ) {
if ( person instanceof Man ) {
assertThat( ( (Man) person ).getHobby(), is( john.getHobby() ) );
}
else if ( person instanceof Woman ) {
assertThat( ( (Woman) person ).getJob(), is( jane.getJob() ) );
}
else if ( person instanceof Child ) {
if ( person.getName().equals( "Susan" ) ) {
assertThat( ( (Child) person ).getFavouriteToy(), is( susan.getFavouriteToy() ) );
}
else {
assertThat( ( (Child) person ).getFavouriteToy(), is( mark.getFavouriteToy() ) );
}
}
else {
fail( "Unexpected result: " + person );
}
}
else {
assertThat( ( (Child) person ).getFavouriteToy(), is( mark.getFavouriteToy() ) );
}
}
else {
fail( "Unexpected result: " + person );
}
}
} );
} );
}
@Entity(name = "Family")

View File

@ -1,45 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.inheritance.discriminator;
import org.junit.Test;
import org.hibernate.Session;
import org.hibernate.dialect.PostgreSQL81Dialect;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
/**
* @author Pawel Stawicki
*/
@RequiresDialect( value = {PostgreSQL81Dialect.class, PostgreSQLDialect.class}, jiraKey = "HHH-6580" )
public class PersistChildEntitiesWithDiscriminatorTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { ParentEntity.class, InheritingEntity.class };
}
@Test
public void doIt() {
Session session = openSession();
session.beginTransaction();
// we need the 2 inserts so that the id is incremented on the second get-generated-keys-result set, since
// on the first insert both the pk and the discriminator values are 1
session.save( new InheritingEntity( "yabba" ) );
session.save( new InheritingEntity( "dabba" ) );
session.getTransaction().commit();
session.close();
session = openSession();
session.beginTransaction();
session.createQuery( "delete ParentEntity" ).executeUpdate();
session.getTransaction().commit();
session.close();
}
}