Re-enabled additional Inheritance related tests and fixed issues with initializer for subclasses
This commit is contained in:
parent
923a7d8d07
commit
7470138e0f
|
@ -312,6 +312,7 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
|
|||
.getFromClauseAccess()
|
||||
.getTableGroup( fetchParent.getNavigablePath() );
|
||||
return new CircularFetchImpl(
|
||||
this,
|
||||
getEntityMappingType(),
|
||||
getTiming(),
|
||||
fetchablePath,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -63,5 +63,5 @@ public interface FetchParent extends DomainResultGraphNode {
|
|||
*/
|
||||
List<Fetch> getFetches();
|
||||
|
||||
Fetch findFetch(String fetchableName);
|
||||
Fetch findFetch(Fetchable fetchable);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ public class DelayedCollectionAssembler extends AbstractCollectionAssembler {
|
|||
fetchedMapping,
|
||||
() -> (CollectionInitializer) creationState.resolveInitializer(
|
||||
fetchPath,
|
||||
fetchedMapping,
|
||||
() -> new DelayedCollectionInitializer( fetchPath, fetchedMapping, parentAccess )
|
||||
)
|
||||
|
||||
|
|
|
@ -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() + "]"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ public class SelectEagerCollectionAssembler extends AbstractCollectionAssembler
|
|||
fetchedMapping,
|
||||
() -> (CollectionInitializer) creationState.resolveInitializer(
|
||||
fetchPath,
|
||||
fetchedMapping,
|
||||
() -> new SelectEagerCollectionInitializer( fetchPath, fetchedMapping, parentAccess )
|
||||
)
|
||||
);
|
||||
|
|
|
@ -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() )
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 )
|
||||
)
|
||||
);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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 ),
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -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")
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue