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()
|
.getFromClauseAccess()
|
||||||
.getTableGroup( fetchParent.getNavigablePath() );
|
.getTableGroup( fetchParent.getNavigablePath() );
|
||||||
return new CircularFetchImpl(
|
return new CircularFetchImpl(
|
||||||
|
this,
|
||||||
getEntityMappingType(),
|
getEntityMappingType(),
|
||||||
getTiming(),
|
getTiming(),
|
||||||
fetchablePath,
|
fetchablePath,
|
||||||
|
|
|
@ -55,12 +55,12 @@ public abstract class AbstractFetchParent implements FetchParent {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Fetch findFetch(String fetchableName) {
|
public Fetch findFetch(Fetchable fetchable) {
|
||||||
if ( fetches != null ) {
|
if ( fetches != null ) {
|
||||||
for ( Fetch fetch : fetches ) {
|
for ( Fetch fetch : fetches ) {
|
||||||
final Fetchable fetchedMapping = fetch.getFetchedMapping();
|
final Fetchable fetchedMapping = fetch.getFetchedMapping();
|
||||||
if ( fetchedMapping != null && fetchedMapping
|
if ( fetchedMapping != null
|
||||||
.getFetchableName().equals( fetchableName ) ) {
|
&& fetchedMapping.getNavigableRole().equals( fetchable.getNavigableRole() ) ) {
|
||||||
return fetch;
|
return fetch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.sql.results.graph;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
|
|
||||||
|
@ -15,6 +16,11 @@ import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface AssemblerCreationState {
|
public interface AssemblerCreationState {
|
||||||
Initializer resolveInitializer(NavigablePath navigablePath, Supplier<Initializer> producer);
|
|
||||||
|
Initializer resolveInitializer(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
ModelPart fetchedModelPart,
|
||||||
|
Supplier<Initializer> producer);
|
||||||
|
|
||||||
SqlAstCreationContext getSqlAstCreationContext();
|
SqlAstCreationContext getSqlAstCreationContext();
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,5 +63,5 @@ public interface FetchParent extends DomainResultGraphNode {
|
||||||
*/
|
*/
|
||||||
List<Fetch> getFetches();
|
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.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
import org.hibernate.sql.results.graph.FetchParent;
|
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.FetchableContainer;
|
||||||
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
|
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
|
||||||
import org.hibernate.sql.results.graph.collection.CollectionResultGraphNode;
|
import org.hibernate.sql.results.graph.collection.CollectionResultGraphNode;
|
||||||
|
@ -81,6 +82,7 @@ public class CollectionDomainResult implements DomainResult, CollectionResultGra
|
||||||
public DomainResultAssembler createResultAssembler(AssemblerCreationState creationState) {
|
public DomainResultAssembler createResultAssembler(AssemblerCreationState creationState) {
|
||||||
final CollectionInitializer initializer = (CollectionInitializer) creationState.resolveInitializer(
|
final CollectionInitializer initializer = (CollectionInitializer) creationState.resolveInitializer(
|
||||||
getNavigablePath(),
|
getNavigablePath(),
|
||||||
|
getReferencedModePart(),
|
||||||
() -> {
|
() -> {
|
||||||
final DomainResultAssembler fkAssembler = fkResult.createResultAssembler( creationState );
|
final DomainResultAssembler fkAssembler = fkResult.createResultAssembler( creationState );
|
||||||
|
|
||||||
|
@ -120,7 +122,7 @@ public class CollectionDomainResult implements DomainResult, CollectionResultGra
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Fetch findFetch(String fetchableName) {
|
public Fetch findFetch(Fetchable fetchable) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ public class DelayedCollectionAssembler extends AbstractCollectionAssembler {
|
||||||
fetchedMapping,
|
fetchedMapping,
|
||||||
() -> (CollectionInitializer) creationState.resolveInitializer(
|
() -> (CollectionInitializer) creationState.resolveInitializer(
|
||||||
fetchPath,
|
fetchPath,
|
||||||
|
fetchedMapping,
|
||||||
() -> new DelayedCollectionInitializer( fetchPath, fetchedMapping, parentAccess )
|
() -> 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.Fetch;
|
||||||
import org.hibernate.sql.results.graph.FetchParent;
|
import org.hibernate.sql.results.graph.FetchParent;
|
||||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
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.FetchableContainer;
|
||||||
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
|
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
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) {
|
public DomainResultAssembler createAssembler(FetchParentAccess parentAccess, AssemblerCreationState creationState) {
|
||||||
final CollectionInitializer initializer = (CollectionInitializer) creationState.resolveInitializer(
|
final CollectionInitializer initializer = (CollectionInitializer) creationState.resolveInitializer(
|
||||||
getNavigablePath(),
|
getNavigablePath(),
|
||||||
|
getReferencedModePart(),
|
||||||
() -> {
|
() -> {
|
||||||
final DomainResultAssembler keyContainerAssembler = keyContainerResult.createResultAssembler( creationState );
|
final DomainResultAssembler keyContainerAssembler = keyContainerResult.createResultAssembler( creationState );
|
||||||
|
|
||||||
|
@ -160,17 +162,17 @@ public class EagerCollectionFetch extends CollectionFetch implements FetchParent
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Fetch findFetch(String fetchableName) {
|
public Fetch findFetch(Fetchable fetchable) {
|
||||||
if ( CollectionPart.Nature.ELEMENT.getName().equals( fetchableName ) ) {
|
if ( CollectionPart.Nature.ELEMENT.getName().equals( fetchable.getFetchableName() ) ) {
|
||||||
return elementFetch;
|
return elementFetch;
|
||||||
}
|
}
|
||||||
else if ( CollectionPart.Nature.INDEX.getName().equals( fetchableName ) ) {
|
else if ( CollectionPart.Nature.INDEX.getName().equals( fetchable.getFetchableName() ) ) {
|
||||||
return indexFetch;
|
return indexFetch;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Unknown fetchable [" + getFetchedMapping().getCollectionDescriptor().getRole() +
|
"Unknown fetchable [" + getFetchedMapping().getCollectionDescriptor().getRole() +
|
||||||
" -> " + fetchableName + "]"
|
" -> " + fetchable.getFetchableName() + "]"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ public class SelectEagerCollectionAssembler extends AbstractCollectionAssembler
|
||||||
fetchedMapping,
|
fetchedMapping,
|
||||||
() -> (CollectionInitializer) creationState.resolveInitializer(
|
() -> (CollectionInitializer) creationState.resolveInitializer(
|
||||||
fetchPath,
|
fetchPath,
|
||||||
|
fetchedMapping,
|
||||||
() -> new SelectEagerCollectionInitializer( fetchPath, fetchedMapping, parentAccess )
|
() -> new SelectEagerCollectionInitializer( fetchPath, fetchedMapping, parentAccess )
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -55,7 +55,7 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
||||||
|
|
||||||
embeddableTypeDescriptor.visitStateArrayContributors(
|
embeddableTypeDescriptor.visitStateArrayContributors(
|
||||||
stateArrayContributor -> {
|
stateArrayContributor -> {
|
||||||
final Fetch fetch = resultDescriptor.findFetch( stateArrayContributor.getFetchableName() );
|
final Fetch fetch = resultDescriptor.findFetch( stateArrayContributor );
|
||||||
|
|
||||||
final DomainResultAssembler stateAssembler = fetch == null
|
final DomainResultAssembler stateAssembler = fetch == null
|
||||||
? new NullValueAssembler( stateArrayContributor.getJavaTypeDescriptor() )
|
? new NullValueAssembler( stateArrayContributor.getJavaTypeDescriptor() )
|
||||||
|
|
|
@ -113,6 +113,7 @@ public class EmbeddableFetchImpl extends AbstractFetchParent implements Embeddab
|
||||||
AssemblerCreationState creationState) {
|
AssemblerCreationState creationState) {
|
||||||
final EmbeddableInitializer initializer = (EmbeddableInitializer) creationState.resolveInitializer(
|
final EmbeddableInitializer initializer = (EmbeddableInitializer) creationState.resolveInitializer(
|
||||||
getNavigablePath(),
|
getNavigablePath(),
|
||||||
|
getReferencedModePart(),
|
||||||
() -> new EmbeddableFetchInitializer(
|
() -> new EmbeddableFetchInitializer(
|
||||||
parentAccess,
|
parentAccess,
|
||||||
this,
|
this,
|
||||||
|
|
|
@ -39,6 +39,7 @@ public class EmbeddableForeignKeyResultImpl<T>
|
||||||
extends AbstractFetchParent
|
extends AbstractFetchParent
|
||||||
implements EmbeddableResultGraphNode, DomainResult<T> {
|
implements EmbeddableResultGraphNode, DomainResult<T> {
|
||||||
|
|
||||||
|
private static final String ROLE_LOCAL_NAME = "{fk}";
|
||||||
private final String resultVariable;
|
private final String resultVariable;
|
||||||
|
|
||||||
public EmbeddableForeignKeyResultImpl(
|
public EmbeddableForeignKeyResultImpl(
|
||||||
|
@ -47,15 +48,15 @@ public class EmbeddableForeignKeyResultImpl<T>
|
||||||
EmbeddableValuedModelPart embeddableValuedModelPart,
|
EmbeddableValuedModelPart embeddableValuedModelPart,
|
||||||
String resultVariable,
|
String resultVariable,
|
||||||
DomainResultCreationState creationState) {
|
DomainResultCreationState creationState) {
|
||||||
super( embeddableValuedModelPart.getEmbeddableTypeDescriptor(), navigablePath );
|
super( embeddableValuedModelPart.getEmbeddableTypeDescriptor(), navigablePath.append( ROLE_LOCAL_NAME ) );
|
||||||
this.resultVariable = resultVariable;
|
this.resultVariable = resultVariable;
|
||||||
fetches = new ArrayList<>();
|
fetches = new ArrayList<>();
|
||||||
MutableInteger index = new MutableInteger();
|
MutableInteger index = new MutableInteger();
|
||||||
|
|
||||||
embeddableValuedModelPart.visitFetchables(
|
embeddableValuedModelPart.visitFetchables(
|
||||||
fetchable -> {
|
fetchable ->
|
||||||
generateFetches( sqlSelections, navigablePath, creationState, index, fetchable );
|
generateFetches( sqlSelections, navigablePath, creationState, index, fetchable )
|
||||||
},
|
,
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -120,6 +121,7 @@ public class EmbeddableForeignKeyResultImpl<T>
|
||||||
public DomainResultAssembler<T> createResultAssembler(AssemblerCreationState creationState) {
|
public DomainResultAssembler<T> createResultAssembler(AssemblerCreationState creationState) {
|
||||||
final EmbeddableInitializer initializer = (EmbeddableInitializer) creationState.resolveInitializer(
|
final EmbeddableInitializer initializer = (EmbeddableInitializer) creationState.resolveInitializer(
|
||||||
getNavigablePath(),
|
getNavigablePath(),
|
||||||
|
getReferencedModePart(),
|
||||||
() -> new EmbeddableResultInitializer(this, creationState )
|
() -> new EmbeddableResultInitializer(this, creationState )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -127,19 +129,14 @@ public class EmbeddableForeignKeyResultImpl<T>
|
||||||
return new EmbeddableAssembler( initializer );
|
return new EmbeddableAssembler( initializer );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public NavigablePath getNavigablePath() {
|
|
||||||
return super.getNavigablePath().append( "{fk}");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EmbeddableMappingType getReferencedMappingType() {
|
public EmbeddableMappingType getReferencedMappingType() {
|
||||||
return (EmbeddableMappingType) getFetchContainer().getPartMappingType();
|
return (EmbeddableMappingType) getFetchContainer().getPartMappingType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Fetch findFetch(String fetchableName) {
|
public Fetch findFetch(Fetchable fetchable) {
|
||||||
return super.findFetch( fetchableName );
|
return super.findFetch( fetchable );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -87,6 +87,7 @@ public class EmbeddableResultImpl<T> extends AbstractFetchParent implements Embe
|
||||||
public DomainResultAssembler<T> createResultAssembler(AssemblerCreationState creationState) {
|
public DomainResultAssembler<T> createResultAssembler(AssemblerCreationState creationState) {
|
||||||
final EmbeddableInitializer initializer = (EmbeddableInitializer) creationState.resolveInitializer(
|
final EmbeddableInitializer initializer = (EmbeddableInitializer) creationState.resolveInitializer(
|
||||||
getNavigablePath(),
|
getNavigablePath(),
|
||||||
|
getReferencedModePart(),
|
||||||
() -> new EmbeddableResultInitializer(
|
() -> new EmbeddableResultInitializer(
|
||||||
this,
|
this,
|
||||||
creationState
|
creationState
|
||||||
|
|
|
@ -34,6 +34,8 @@ import org.hibernate.event.spi.PreLoadEvent;
|
||||||
import org.hibernate.event.spi.PreLoadEventListener;
|
import org.hibernate.event.spi.PreLoadEventListener;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
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.EntityPersister;
|
||||||
import org.hibernate.persister.entity.Loadable;
|
import org.hibernate.persister.entity.Loadable;
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
|
@ -67,6 +69,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
|
|
||||||
private final EntityPersister entityDescriptor;
|
private final EntityPersister entityDescriptor;
|
||||||
private final EntityPersister rootEntityDescriptor;
|
private final EntityPersister rootEntityDescriptor;
|
||||||
|
private EntityPersister concreteDescriptor;
|
||||||
private final NavigablePath navigablePath;
|
private final NavigablePath navigablePath;
|
||||||
private final LockMode lockMode;
|
private final LockMode lockMode;
|
||||||
|
|
||||||
|
@ -80,7 +83,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
private final Map<AttributeMapping, DomainResultAssembler> assemblerMap;
|
private final Map<AttributeMapping, DomainResultAssembler> assemblerMap;
|
||||||
|
|
||||||
// per-row state
|
// per-row state
|
||||||
private EntityPersister concreteDescriptor;
|
private final EntityValuedModelPart referencedModelPart;
|
||||||
private EntityKey entityKey;
|
private EntityKey entityKey;
|
||||||
private Object entityInstance;
|
private Object entityInstance;
|
||||||
private boolean missing;
|
private boolean missing;
|
||||||
|
@ -100,7 +103,8 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
AssemblerCreationState creationState) {
|
AssemblerCreationState creationState) {
|
||||||
super( );
|
super( );
|
||||||
|
|
||||||
this.entityDescriptor = (EntityPersister) resultDescriptor.getEntityValuedModelPart().getEntityMappingType();
|
this.referencedModelPart = resultDescriptor.getEntityValuedModelPart();
|
||||||
|
this.entityDescriptor = (EntityPersister) referencedModelPart.getEntityMappingType();
|
||||||
|
|
||||||
final String rootEntityName = entityDescriptor.getRootEntityName();
|
final String rootEntityName = entityDescriptor.getRootEntityName();
|
||||||
if ( rootEntityName == null || rootEntityName.equals( entityDescriptor.getEntityName() ) ) {
|
if ( rootEntityName == null || rootEntityName.equals( entityDescriptor.getEntityName() ) ) {
|
||||||
|
@ -117,10 +121,15 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
this.identifierAssembler = identifierResult.createResultAssembler(
|
this.identifierAssembler = identifierResult.createResultAssembler(
|
||||||
new AssemblerCreationState() {
|
new AssemblerCreationState() {
|
||||||
@Override
|
@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++ ) {
|
for ( int i = 0; i < identifierInitializers.size(); i++ ) {
|
||||||
final Initializer existing = identifierInitializers.get( 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;
|
return existing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,7 +194,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
// note that lazy proxies or uninitialized collections count against
|
// note that lazy proxies or uninitialized collections count against
|
||||||
// that in the affirmative
|
// that in the affirmative
|
||||||
|
|
||||||
final Fetch fetch = resultDescriptor.findFetch( fetchable.getFetchableName() );
|
final Fetch fetch = resultDescriptor.findFetch( fetchable );
|
||||||
|
|
||||||
final DomainResultAssembler stateAssembler;
|
final DomainResultAssembler stateAssembler;
|
||||||
if ( fetch == null ) {
|
if ( fetch == null ) {
|
||||||
|
@ -201,6 +210,11 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelPart getInitializedPart(){
|
||||||
|
return referencedModelPart;
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract String getSimpleConcreteImplName();
|
protected abstract String getSimpleConcreteImplName();
|
||||||
|
|
||||||
public NavigablePath getNavigablePath() {
|
public NavigablePath getNavigablePath() {
|
||||||
|
@ -268,6 +282,10 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
|
|
||||||
final SharedSessionContractImplementor session = rowProcessingState.getJdbcValuesSourceProcessingState().getSession();
|
final SharedSessionContractImplementor session = rowProcessingState.getJdbcValuesSourceProcessingState().getSession();
|
||||||
concreteDescriptor = determineConcreteEntityDescriptor( rowProcessingState, session );
|
concreteDescriptor = determineConcreteEntityDescriptor( rowProcessingState, session );
|
||||||
|
if ( concreteDescriptor == null ) {
|
||||||
|
missing = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
initializeIdentifier( rowProcessingState );
|
initializeIdentifier( rowProcessingState );
|
||||||
resolveEntityKey( rowProcessingState );
|
resolveEntityKey( rowProcessingState );
|
||||||
|
@ -306,21 +324,22 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
rowProcessingState.getJdbcValuesSourceProcessingState().getProcessingOptions()
|
rowProcessingState.getJdbcValuesSourceProcessingState().getProcessingOptions()
|
||||||
);
|
);
|
||||||
|
|
||||||
final String concreteEntityName = ( (Loadable) rootEntityDescriptor ).getSubclassForDiscriminatorValue( discriminatorValue );
|
final String concreteEntityName = ( (Loadable) entityDescriptor ).getSubclassForDiscriminatorValue( discriminatorValue );
|
||||||
|
|
||||||
if ( concreteEntityName == null ) {
|
if ( concreteEntityName == null ) {
|
||||||
// oops - we got an instance of another class hierarchy branch
|
// oops - we got an instance of another class hierarchy branch
|
||||||
throw new WrongClassException(
|
// throw new WrongClassException(
|
||||||
"Discriminator: " + discriminatorValue,
|
// "Discriminator: " + discriminatorValue,
|
||||||
entityKey.getIdentifier(),
|
// entityKey.getIdentifier(),
|
||||||
entityDescriptor.getEntityName()
|
// entityDescriptor.getEntityName()
|
||||||
);
|
// );
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final EntityPersister concreteType = session.getFactory().getMetamodel().findEntityDescriptor( concreteEntityName );
|
final EntityPersister concreteType = session.getFactory().getMetamodel().findEntityDescriptor( concreteEntityName );
|
||||||
|
|
||||||
// verify that the `entityDescriptor` is either == concreteType or its super-type
|
// verify that the `entityDescriptor` is either == concreteType or its super-type
|
||||||
assert concreteType.isTypeOrSuperType( rootEntityDescriptor );
|
assert concreteType.isTypeOrSuperType( entityDescriptor );
|
||||||
|
|
||||||
return concreteType;
|
return concreteType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,6 @@ import org.hibernate.persister.entity.EntityPersister;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface EntityInitializer extends Initializer, FetchParentAccess {
|
public interface EntityInitializer extends Initializer, FetchParentAccess {
|
||||||
@Override
|
|
||||||
default ModelPart getInitializedPart() {
|
|
||||||
return getEntityDescriptor();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the descriptor for the type of entity being initialized
|
* 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.query.NavigablePath;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
import org.hibernate.sql.results.graph.FetchParent;
|
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.EntityFetch;
|
||||||
import org.hibernate.sql.results.graph.entity.EntityValuedFetchable;
|
import org.hibernate.sql.results.graph.entity.EntityValuedFetchable;
|
||||||
|
|
||||||
|
@ -59,7 +60,7 @@ public abstract class AbstractNonJoinedEntityFetch implements EntityFetch {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Fetch findFetch(String fetchableName) {
|
public Fetch findFetch(Fetchable fetchable) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,11 +47,13 @@ public class EntityDelayedFetchImpl extends AbstractNonJoinedEntityFetch {
|
||||||
public DomainResultAssembler createAssembler(
|
public DomainResultAssembler createAssembler(
|
||||||
FetchParentAccess parentAccess,
|
FetchParentAccess parentAccess,
|
||||||
AssemblerCreationState creationState) {
|
AssemblerCreationState creationState) {
|
||||||
|
final NavigablePath navigablePath = getNavigablePath();
|
||||||
final EntityInitializer entityInitializer = (EntityInitializer) creationState.resolveInitializer(
|
final EntityInitializer entityInitializer = (EntityInitializer) creationState.resolveInitializer(
|
||||||
getNavigablePath(),
|
navigablePath,
|
||||||
|
getEntityValuedModelPart(),
|
||||||
() -> new EntityDelayedFetchInitializer(
|
() -> new EntityDelayedFetchInitializer(
|
||||||
getNavigablePath(),
|
navigablePath,
|
||||||
getEntityValuedModelPart().getEntityMappingType().getEntityPersister(),
|
getEntityValuedModelPart(),
|
||||||
keyResult.createResultAssembler( creationState )
|
keyResult.createResultAssembler( creationState )
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -12,6 +12,8 @@ import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
import org.hibernate.engine.spi.EntityKey;
|
import org.hibernate.engine.spi.EntityKey;
|
||||||
import org.hibernate.engine.spi.PersistenceContext;
|
import org.hibernate.engine.spi.PersistenceContext;
|
||||||
import org.hibernate.internal.log.LoggingHelper;
|
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.persister.entity.EntityPersister;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.sql.results.graph.AbstractFetchParentAccess;
|
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 {
|
public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess implements EntityInitializer {
|
||||||
|
|
||||||
private final NavigablePath navigablePath;
|
private final NavigablePath navigablePath;
|
||||||
private final EntityPersister concreteDescriptor;
|
private final EntityValuedModelPart referencedModelPart;
|
||||||
private final DomainResultAssembler identifierAssembler;
|
private final DomainResultAssembler identifierAssembler;
|
||||||
|
|
||||||
private Object entityInstance;
|
private Object entityInstance;
|
||||||
|
@ -35,10 +37,10 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
|
||||||
|
|
||||||
public EntityDelayedFetchInitializer(
|
public EntityDelayedFetchInitializer(
|
||||||
NavigablePath fetchedNavigable,
|
NavigablePath fetchedNavigable,
|
||||||
EntityPersister concreteDescriptor,
|
EntityValuedModelPart referencedModelPart,
|
||||||
DomainResultAssembler identifierAssembler) {
|
DomainResultAssembler identifierAssembler) {
|
||||||
this.navigablePath = fetchedNavigable;
|
this.navigablePath = fetchedNavigable;
|
||||||
this.concreteDescriptor = concreteDescriptor;
|
this.referencedModelPart = referencedModelPart;
|
||||||
this.identifierAssembler = identifierAssembler;
|
this.identifierAssembler = identifierAssembler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +54,11 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
|
||||||
// nothing to do
|
// nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelPart getInitializedPart(){
|
||||||
|
return referencedModelPart;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resolveInstance(RowProcessingState rowProcessingState) {
|
public void resolveInstance(RowProcessingState rowProcessingState) {
|
||||||
if ( entityInstance != null ) {
|
if ( entityInstance != null ) {
|
||||||
|
@ -64,6 +71,8 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
|
||||||
entityInstance = null;
|
entityInstance = null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
final EntityPersister concreteDescriptor = referencedModelPart.getEntityMappingType().getEntityPersister();
|
||||||
|
|
||||||
final EntityKey entityKey = new EntityKey( identifier, concreteDescriptor );
|
final EntityKey entityKey = new EntityKey( identifier, concreteDescriptor );
|
||||||
PersistenceContext persistenceContext = rowProcessingState.getSession().getPersistenceContext();
|
PersistenceContext persistenceContext = rowProcessingState.getSession().getPersistenceContext();
|
||||||
final Object entity = persistenceContext.getEntity( entityKey );
|
final Object entity = persistenceContext.getEntity( entityKey );
|
||||||
|
@ -120,7 +129,7 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityPersister getEntityDescriptor() {
|
public EntityPersister getEntityDescriptor() {
|
||||||
return concreteDescriptor;
|
return referencedModelPart.getEntityMappingType().getEntityPersister();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.sql.results.graph.entity.internal;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.engine.FetchTiming;
|
import org.hibernate.engine.FetchTiming;
|
||||||
|
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
|
@ -49,6 +50,7 @@ public class EntityFetchJoinedImpl extends AbstractNonLazyEntityFetch {
|
||||||
AssemblerCreationState creationState) {
|
AssemblerCreationState creationState) {
|
||||||
return (EntityInitializer) creationState.resolveInitializer(
|
return (EntityInitializer) creationState.resolveInitializer(
|
||||||
getNavigablePath(),
|
getNavigablePath(),
|
||||||
|
getEntityValuedModelPart(),
|
||||||
() -> new EntityJoinedFetchInitializer(
|
() -> new EntityJoinedFetchInitializer(
|
||||||
entityResult,
|
entityResult,
|
||||||
getNavigablePath(),
|
getNavigablePath(),
|
||||||
|
|
|
@ -56,12 +56,14 @@ public class EntityFetchSelectImpl extends AbstractNonJoinedEntityFetch {
|
||||||
public DomainResultAssembler createAssembler(FetchParentAccess parentAccess, AssemblerCreationState creationState) {
|
public DomainResultAssembler createAssembler(FetchParentAccess parentAccess, AssemblerCreationState creationState) {
|
||||||
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
|
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
|
||||||
getNavigablePath(),
|
getNavigablePath(),
|
||||||
|
getFetchedMapping(),
|
||||||
() -> {
|
() -> {
|
||||||
|
|
||||||
EntityPersister entityPersister = getReferencedMappingContainer().getEntityPersister();
|
EntityPersister entityPersister = getReferencedMappingContainer().getEntityPersister();
|
||||||
|
|
||||||
if ( selectByUniqueKey ) {
|
if ( selectByUniqueKey ) {
|
||||||
return new EntitySelectFetchByUniqueKeyInitializer(
|
return new EntitySelectFetchByUniqueKeyInitializer(
|
||||||
|
getFetchedMapping(),
|
||||||
(ToOneAttributeMapping) getFetchedMapping(),
|
(ToOneAttributeMapping) getFetchedMapping(),
|
||||||
getNavigablePath(),
|
getNavigablePath(),
|
||||||
entityPersister,
|
entityPersister,
|
||||||
|
@ -70,6 +72,7 @@ public class EntityFetchSelectImpl extends AbstractNonJoinedEntityFetch {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return new EntitySelectFetchInitializer(
|
return new EntitySelectFetchInitializer(
|
||||||
|
getFetchedMapping(),
|
||||||
getNavigablePath(),
|
getNavigablePath(),
|
||||||
entityPersister,
|
entityPersister,
|
||||||
result.createResultAssembler( creationState ),
|
result.createResultAssembler( creationState ),
|
||||||
|
|
|
@ -70,6 +70,7 @@ public class EntityResultImpl extends AbstractEntityResultGraphNode implements E
|
||||||
public DomainResultAssembler createResultAssembler(AssemblerCreationState creationState) {
|
public DomainResultAssembler createResultAssembler(AssemblerCreationState creationState) {
|
||||||
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
|
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
|
||||||
getNavigablePath(),
|
getNavigablePath(),
|
||||||
|
getReferencedModePart(),
|
||||||
() -> new EntityResultInitializer(
|
() -> new EntityResultInitializer(
|
||||||
this,
|
this,
|
||||||
getNavigablePath(),
|
getNavigablePath(),
|
||||||
|
|
|
@ -33,6 +33,7 @@ public class EntityResultJoinedSubclassImpl extends EntityResultImpl {
|
||||||
public DomainResultAssembler createResultAssembler(AssemblerCreationState creationState) {
|
public DomainResultAssembler createResultAssembler(AssemblerCreationState creationState) {
|
||||||
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
|
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
|
||||||
getNavigablePath(),
|
getNavigablePath(),
|
||||||
|
getReferencedModePart(),
|
||||||
() -> new EntityResultInitializer(
|
() -> new EntityResultInitializer(
|
||||||
this,
|
this,
|
||||||
getNavigablePath(),
|
getNavigablePath(),
|
||||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.sql.results.graph.entity.internal;
|
||||||
import org.hibernate.engine.spi.EntityUniqueKey;
|
import org.hibernate.engine.spi.EntityUniqueKey;
|
||||||
import org.hibernate.engine.spi.PersistenceContext;
|
import org.hibernate.engine.spi.PersistenceContext;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
|
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.entity.UniqueKeyLoadable;
|
import org.hibernate.persister.entity.UniqueKeyLoadable;
|
||||||
|
@ -23,12 +24,13 @@ public class EntitySelectFetchByUniqueKeyInitializer extends EntitySelectFetchIn
|
||||||
private final ToOneAttributeMapping fetchedAttribute;
|
private final ToOneAttributeMapping fetchedAttribute;
|
||||||
|
|
||||||
public EntitySelectFetchByUniqueKeyInitializer(
|
public EntitySelectFetchByUniqueKeyInitializer(
|
||||||
|
EntityValuedModelPart referencedModelPart,
|
||||||
ToOneAttributeMapping fetchedAttribute,
|
ToOneAttributeMapping fetchedAttribute,
|
||||||
NavigablePath fetchedNavigable,
|
NavigablePath fetchedNavigable,
|
||||||
EntityPersister concreteDescriptor,
|
EntityPersister concreteDescriptor,
|
||||||
DomainResultAssembler identifierAssembler,
|
DomainResultAssembler identifierAssembler,
|
||||||
boolean nullable) {
|
boolean nullable) {
|
||||||
super( fetchedNavigable, concreteDescriptor, identifierAssembler, nullable );
|
super( referencedModelPart, fetchedNavigable, concreteDescriptor, identifierAssembler, nullable );
|
||||||
this.fetchedAttribute = fetchedAttribute;
|
this.fetchedAttribute = fetchedAttribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@ import org.hibernate.engine.spi.PersistenceContext;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.internal.log.LoggingHelper;
|
import org.hibernate.internal.log.LoggingHelper;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
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.persister.entity.EntityPersister;
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
import org.hibernate.query.NavigablePath;
|
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.Initializer;
|
||||||
import org.hibernate.sql.results.graph.entity.EntityInitializer;
|
import org.hibernate.sql.results.graph.entity.EntityInitializer;
|
||||||
import org.hibernate.sql.results.graph.entity.EntityLoadingLogger;
|
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.EntityValuedFetchable;
|
||||||
import org.hibernate.sql.results.graph.entity.LoadingEntityEntry;
|
import org.hibernate.sql.results.graph.entity.LoadingEntityEntry;
|
||||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||||
|
@ -40,9 +43,12 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
|
||||||
|
|
||||||
protected final EntityPersister concreteDescriptor;
|
protected final EntityPersister concreteDescriptor;
|
||||||
protected final DomainResultAssembler identifierAssembler;
|
protected final DomainResultAssembler identifierAssembler;
|
||||||
|
private final EntityValuedModelPart referencedModelPart;
|
||||||
|
|
||||||
protected Object entityInstance;
|
protected Object entityInstance;
|
||||||
|
|
||||||
public EntitySelectFetchInitializer(
|
public EntitySelectFetchInitializer(
|
||||||
|
EntityValuedModelPart referencedModelPart,
|
||||||
NavigablePath fetchedNavigable,
|
NavigablePath fetchedNavigable,
|
||||||
EntityPersister concreteDescriptor,
|
EntityPersister concreteDescriptor,
|
||||||
DomainResultAssembler identifierAssembler,
|
DomainResultAssembler identifierAssembler,
|
||||||
|
@ -51,9 +57,14 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
|
||||||
this.concreteDescriptor = concreteDescriptor;
|
this.concreteDescriptor = concreteDescriptor;
|
||||||
this.identifierAssembler = identifierAssembler;
|
this.identifierAssembler = identifierAssembler;
|
||||||
this.nullable = nullable;
|
this.nullable = nullable;
|
||||||
|
this.referencedModelPart = referencedModelPart;
|
||||||
this.isEnhancedForLazyLoading = concreteDescriptor.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading();
|
this.isEnhancedForLazyLoading = concreteDescriptor.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ModelPart getInitializedPart(){
|
||||||
|
return referencedModelPart;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NavigablePath getNavigablePath() {
|
public NavigablePath getNavigablePath() {
|
||||||
return navigablePath;
|
return navigablePath;
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.engine.spi.BatchFetchQueue;
|
||||||
import org.hibernate.engine.spi.CollectionEntry;
|
import org.hibernate.engine.spi.CollectionEntry;
|
||||||
import org.hibernate.engine.spi.PersistenceContext;
|
import org.hibernate.engine.spi.PersistenceContext;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
|
@ -44,17 +45,22 @@ public class ResultsHelper {
|
||||||
//noinspection rawtypes
|
//noinspection rawtypes
|
||||||
final List<DomainResultAssembler> assemblers = jdbcValues.getValuesMapping().resolveAssemblers(
|
final List<DomainResultAssembler> assemblers = jdbcValues.getValuesMapping().resolveAssemblers(
|
||||||
new AssemblerCreationState() {
|
new AssemblerCreationState() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Initializer resolveInitializer(
|
public Initializer resolveInitializer(
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
|
ModelPart fetchedModelPart,
|
||||||
Supplier<Initializer> producer) {
|
Supplier<Initializer> producer) {
|
||||||
final Initializer existing = initializerMap.get( navigablePath );
|
final Initializer existing = initializerMap.get( navigablePath );
|
||||||
if ( existing != null ) {
|
if ( existing != null ) {
|
||||||
ResultsLogger.LOGGER.debugf(
|
if ( fetchedModelPart.getNavigableRole().equals(
|
||||||
"Returning previously-registered initializer : %s",
|
existing.getInitializedPart().getNavigableRole() ) ) {
|
||||||
existing
|
ResultsLogger.LOGGER.debugf(
|
||||||
);
|
"Returning previously-registered initializer : %s",
|
||||||
return existing;
|
existing
|
||||||
|
);
|
||||||
|
return existing;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final Initializer initializer = producer.get();
|
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.Association;
|
||||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
|
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||||
import org.hibernate.metamodel.mapping.MappingType;
|
import org.hibernate.metamodel.mapping.MappingType;
|
||||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||||
|
@ -39,6 +40,7 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
*/
|
*/
|
||||||
public class CircularFetchImpl implements BiDirectionalFetch, Association {
|
public class CircularFetchImpl implements BiDirectionalFetch, Association {
|
||||||
private DomainResult keyResult;
|
private DomainResult keyResult;
|
||||||
|
private EntityValuedModelPart referencedModelPart;
|
||||||
private final EntityMappingType entityMappingType;
|
private final EntityMappingType entityMappingType;
|
||||||
private final FetchTiming timing;
|
private final FetchTiming timing;
|
||||||
private final NavigablePath navigablePath;
|
private final NavigablePath navigablePath;
|
||||||
|
@ -48,6 +50,7 @@ public class CircularFetchImpl implements BiDirectionalFetch, Association {
|
||||||
private final NavigablePath referencedNavigablePath;
|
private final NavigablePath referencedNavigablePath;
|
||||||
|
|
||||||
public CircularFetchImpl(
|
public CircularFetchImpl(
|
||||||
|
EntityValuedModelPart referencedModelPart,
|
||||||
EntityMappingType entityMappingType,
|
EntityMappingType entityMappingType,
|
||||||
FetchTiming timing,
|
FetchTiming timing,
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
|
@ -55,6 +58,7 @@ public class CircularFetchImpl implements BiDirectionalFetch, Association {
|
||||||
ToOneAttributeMapping fetchable,
|
ToOneAttributeMapping fetchable,
|
||||||
NavigablePath referencedNavigablePath,
|
NavigablePath referencedNavigablePath,
|
||||||
DomainResult keyResult) {
|
DomainResult keyResult) {
|
||||||
|
this.referencedModelPart = referencedModelPart;
|
||||||
this.entityMappingType = entityMappingType;
|
this.entityMappingType = entityMappingType;
|
||||||
this.timing = timing;
|
this.timing = timing;
|
||||||
this.fetchParent = fetchParent;
|
this.fetchParent = fetchParent;
|
||||||
|
@ -98,9 +102,11 @@ public class CircularFetchImpl implements BiDirectionalFetch, Association {
|
||||||
|
|
||||||
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
|
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
|
||||||
getNavigablePath(),
|
getNavigablePath(),
|
||||||
|
referencedModelPart,
|
||||||
() -> {
|
() -> {
|
||||||
if ( timing == FetchTiming.IMMEDIATE ) {
|
if ( timing == FetchTiming.IMMEDIATE ) {
|
||||||
return new EntitySelectFetchInitializer(
|
return new EntitySelectFetchInitializer(
|
||||||
|
referencedModelPart,
|
||||||
getReferencedPath(),
|
getReferencedPath(),
|
||||||
entityMappingType.getEntityPersister(),
|
entityMappingType.getEntityPersister(),
|
||||||
resultAssembler,
|
resultAssembler,
|
||||||
|
@ -110,7 +116,7 @@ public class CircularFetchImpl implements BiDirectionalFetch, Association {
|
||||||
else {
|
else {
|
||||||
return new EntityDelayedFetchInitializer(
|
return new EntityDelayedFetchInitializer(
|
||||||
getReferencedPath(),
|
getReferencedPath(),
|
||||||
(EntityPersister) ( (AttributeMapping) fetchable ).getMappedTypeDescriptor(),
|
fetchable,
|
||||||
resultAssembler
|
resultAssembler
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.orm.test.entitygraph.ast;
|
package org.hibernate.orm.test.entitygraph.ast;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
@ -27,9 +29,11 @@ import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.graph.GraphSemantic;
|
import org.hibernate.graph.GraphSemantic;
|
||||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||||
|
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
|
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.query.hql.spi.HqlQueryImplementor;
|
import org.hibernate.query.hql.spi.HqlQueryImplementor;
|
||||||
import org.hibernate.query.spi.QueryImplementor;
|
import org.hibernate.query.spi.QueryImplementor;
|
||||||
import org.hibernate.query.sqm.internal.QuerySqmImpl;
|
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.ast.tree.select.SelectStatement;
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
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.collection.internal.DelayedCollectionFetch;
|
||||||
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
|
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
|
||||||
import org.hibernate.sql.results.graph.entity.EntityFetch;
|
import org.hibernate.sql.results.graph.entity.EntityFetch;
|
||||||
|
@ -183,8 +188,10 @@ public class CriteriaEntityGraphTest implements SessionFactoryScopeAware {
|
||||||
expectedFetchClassByAttributeName.put( "pets", DelayedCollectionFetch.class );
|
expectedFetchClassByAttributeName.put( "pets", DelayedCollectionFetch.class );
|
||||||
expectedFetchClassByAttributeName.put( "company", EntityFetchJoinedImpl.class );
|
expectedFetchClassByAttributeName.put( "company", EntityFetchJoinedImpl.class );
|
||||||
assertThat( fetchClassByAttributeName, is( expectedFetchClassByAttributeName ) );
|
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() );
|
assertThat( companyFetch, notNullValue() );
|
||||||
|
|
||||||
final EntityResult companyEntityResult = ( (EntityFetchJoinedImpl) companyFetch).getEntityResult();
|
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
|
@ParameterizedTest
|
||||||
@EnumSource( GraphSemantic.class )
|
@EnumSource( GraphSemantic.class )
|
||||||
void testBasicElementCollections(GraphSemantic graphSemantic) {
|
void testBasicElementCollections(GraphSemantic graphSemantic) {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.orm.test.entitygraph.ast;
|
package org.hibernate.orm.test.entitygraph.ast;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -26,6 +27,7 @@ import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||||
import org.hibernate.graph.GraphSemantic;
|
import org.hibernate.graph.GraphSemantic;
|
||||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||||
import org.hibernate.loader.ast.internal.LoaderSelectBuilder;
|
import org.hibernate.loader.ast.internal.LoaderSelectBuilder;
|
||||||
|
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
|
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.ast.tree.select.SelectStatement;
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
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.collection.internal.DelayedCollectionFetch;
|
||||||
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
|
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
|
||||||
import org.hibernate.sql.results.graph.entity.EntityFetch;
|
import org.hibernate.sql.results.graph.entity.EntityFetch;
|
||||||
|
@ -180,7 +183,8 @@ public class EntityGraphLoadPlanBuilderTest implements SessionFactoryScopeAware
|
||||||
expectedFetchClassByAttributeName.put( "company", EntityFetchJoinedImpl.class );
|
expectedFetchClassByAttributeName.put( "company", EntityFetchJoinedImpl.class );
|
||||||
assertThat( fetchClassByAttributeName, is( expectedFetchClassByAttributeName ) );
|
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() );
|
assertThat( companyFetch, notNullValue() );
|
||||||
|
|
||||||
final EntityResult companyEntityResult = ( (EntityFetchJoinedImpl) companyFetch).getEntityResult();
|
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
|
@ParameterizedTest
|
||||||
@EnumSource( GraphSemantic.class )
|
@EnumSource( GraphSemantic.class )
|
||||||
void testBasicElementCollections(GraphSemantic graphSemantic) {
|
void testBasicElementCollections(GraphSemantic graphSemantic) {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.orm.test.entitygraph.ast;
|
package org.hibernate.orm.test.entitygraph.ast;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -24,9 +25,11 @@ import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.graph.GraphSemantic;
|
import org.hibernate.graph.GraphSemantic;
|
||||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||||
|
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
|
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.query.hql.spi.HqlQueryImplementor;
|
import org.hibernate.query.hql.spi.HqlQueryImplementor;
|
||||||
import org.hibernate.query.spi.QueryImplementor;
|
import org.hibernate.query.spi.QueryImplementor;
|
||||||
import org.hibernate.query.sqm.internal.QuerySqmImpl;
|
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.ast.tree.select.SelectStatement;
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
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.collection.internal.DelayedCollectionFetch;
|
||||||
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
|
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
|
||||||
import org.hibernate.sql.results.graph.entity.EntityFetch;
|
import org.hibernate.sql.results.graph.entity.EntityFetch;
|
||||||
|
@ -181,7 +185,8 @@ public class HqlEntityGraphTest implements SessionFactoryScopeAware {
|
||||||
expectedFetchClassByAttributeName.put( "company", EntityFetchJoinedImpl.class );
|
expectedFetchClassByAttributeName.put( "company", EntityFetchJoinedImpl.class );
|
||||||
assertThat( fetchClassByAttributeName, is( expectedFetchClassByAttributeName ) );
|
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() );
|
assertThat( companyFetch, notNullValue() );
|
||||||
|
|
||||||
final EntityResult companyEntityResult = ( (EntityFetchJoinedImpl) companyFetch).getEntityResult();
|
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
|
@ParameterizedTest
|
||||||
@EnumSource( GraphSemantic.class )
|
@EnumSource( GraphSemantic.class )
|
||||||
void testBasicElementCollections(GraphSemantic graphSemantic) {
|
void testBasicElementCollections(GraphSemantic graphSemantic) {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import java.io.Serializable;
|
||||||
import javax.persistence.CascadeType;
|
import javax.persistence.CascadeType;
|
||||||
import javax.persistence.DiscriminatorValue;
|
import javax.persistence.DiscriminatorValue;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Inheritance;
|
import javax.persistence.Inheritance;
|
||||||
import javax.persistence.InheritanceType;
|
import javax.persistence.InheritanceType;
|
||||||
|
@ -17,6 +18,8 @@ import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
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.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
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.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
@ -49,8 +53,8 @@ public class MultiSingleTableLoadTest {
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void createTestData(SessionFactoryScope scope) {
|
public void createTestData(SessionFactoryScope scope) {
|
||||||
scope.inTransaction( session -> {
|
scope.inTransaction( session -> {
|
||||||
Holder holder1 = new Holder( 1, new B( 1, new Y( 1 ) ) );
|
Holder holder1 = new Holder( 1, new B( 1, new Y( 1, "y" ) ) );
|
||||||
Holder holder2 = new Holder( 2, new C( 2, new Z( 2 ) ) );
|
Holder holder2 = new Holder( 2, new C( 2, new Z( 2, "z" ) ) );
|
||||||
|
|
||||||
session.persist( holder1 );
|
session.persist( holder1 );
|
||||||
session.persist( holder2 );
|
session.persist( holder2 );
|
||||||
|
@ -76,7 +80,22 @@ public class MultiSingleTableLoadTest {
|
||||||
Holder task1 = session.find( Holder.class, 1L );
|
Holder task1 = session.find( Holder.class, 1L );
|
||||||
Holder task2 = session.find( Holder.class, 2L );
|
Holder task2 = session.find( Holder.class, 2L );
|
||||||
assertNotNull( task1 );
|
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 );
|
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.id = id;
|
||||||
this.a = a;
|
this.a = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public A getA() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity(name = "A")
|
@Entity(name = "A")
|
||||||
|
@ -131,7 +154,7 @@ public class MultiSingleTableLoadTest {
|
||||||
@Entity(name = "B")
|
@Entity(name = "B")
|
||||||
@DiscriminatorValue("B")
|
@DiscriminatorValue("B")
|
||||||
public static class B extends A {
|
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")
|
@JoinColumn(name = "x_id")
|
||||||
private Y x;
|
private Y x;
|
||||||
|
|
||||||
|
@ -142,6 +165,10 @@ public class MultiSingleTableLoadTest {
|
||||||
super( id );
|
super( id );
|
||||||
this.x = x;
|
this.x = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Y getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity(name = "C")
|
@Entity(name = "C")
|
||||||
|
@ -158,6 +185,10 @@ public class MultiSingleTableLoadTest {
|
||||||
super( id );
|
super( id );
|
||||||
this.x = x;
|
this.x = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public X getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity(name = "X")
|
@Entity(name = "X")
|
||||||
|
@ -178,22 +209,36 @@ public class MultiSingleTableLoadTest {
|
||||||
@Entity(name = "Y")
|
@Entity(name = "Y")
|
||||||
@DiscriminatorValue("Y")
|
@DiscriminatorValue("Y")
|
||||||
public static class Y extends X {
|
public static class Y extends X {
|
||||||
|
private String theString;
|
||||||
|
|
||||||
public Y() {
|
public Y() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Y(long id) {
|
public Y(long id, String theString) {
|
||||||
super( id );
|
super( id );
|
||||||
|
this.theString = theString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTheString() {
|
||||||
|
return theString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity(name = "Z")
|
@Entity(name = "Z")
|
||||||
@DiscriminatorValue("Z")
|
@DiscriminatorValue("Z")
|
||||||
public static class Z extends X {
|
public static class Z extends X {
|
||||||
|
private String theString;
|
||||||
|
|
||||||
public Z() {
|
public Z() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Z(long id) {
|
public Z(long id, String theString) {
|
||||||
super( id );
|
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.
|
* 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>.
|
* 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.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -22,20 +22,31 @@ import javax.persistence.OneToMany;
|
||||||
import javax.persistence.OneToOne;
|
import javax.persistence.OneToOne;
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
import org.junit.Before;
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
import org.junit.Test;
|
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.hamcrest.core.Is.is;
|
||||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Davide D'Alto
|
* @author Davide D'Alto
|
||||||
*/
|
*/
|
||||||
@TestForIssue( jiraKey = "HHH-12332")
|
@TestForIssue(jiraKey = "HHH-12332")
|
||||||
public class SingleTableInheritancePersistTest extends BaseCoreFunctionalTestCase {
|
@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 Man john = new Man( "John", "Riding Roller Coasters" );
|
||||||
|
|
||||||
private final Woman jane = new Woman( "Jane", "Hippotherapist" );
|
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<Child> children = new ArrayList<>( Arrays.asList( susan, mark ) );
|
||||||
private final List<Person> familyMembers = Arrays.asList( john, jane, susan, mark );
|
private final List<Person> familyMembers = Arrays.asList( john, jane, susan, mark );
|
||||||
|
|
||||||
@Override
|
@BeforeEach
|
||||||
protected Class<?>[] getAnnotatedClasses() {
|
public void setUp(SessionFactoryScope scope) {
|
||||||
return new Class[] {
|
scope.inTransaction(
|
||||||
Family.class,
|
session -> {
|
||||||
Person.class,
|
jane.setHusband( john );
|
||||||
Child.class,
|
jane.setChildren( children );
|
||||||
Man.class,
|
|
||||||
Woman.class
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
john.setWife( jane );
|
||||||
public void setUp() {
|
john.setChildren( children );
|
||||||
doInHibernate( this::sessionFactory, session -> {
|
|
||||||
jane.setHusband( john );
|
|
||||||
jane.setChildren( children );
|
|
||||||
|
|
||||||
john.setWife( jane );
|
for ( Child child : children ) {
|
||||||
john.setChildren( children );
|
child.setFather( john );
|
||||||
|
child.setMother( jane );
|
||||||
|
}
|
||||||
|
|
||||||
for ( Child child : children ) {
|
for ( Person person : familyMembers ) {
|
||||||
child.setFather( john );
|
family.add( person );
|
||||||
child.setMother( jane );
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for ( Person person : familyMembers ) {
|
session.persist( family );
|
||||||
family.add( person );
|
} );
|
||||||
}
|
|
||||||
|
|
||||||
session.persist( family );
|
|
||||||
} );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPolymorphicAssociation() {
|
public void testPolymorphicAssociation(SessionFactoryScope scope) {
|
||||||
doInHibernate( this::sessionFactory, session1 -> {
|
scope.inTransaction(
|
||||||
Family family = session1.createQuery( "FROM Family f", Family.class ).getSingleResult();
|
session -> {
|
||||||
List<Person> members = family.getMembers();
|
Family family = session.createQuery( "FROM Family f", Family.class ).getSingleResult();
|
||||||
assertThat( members.size(), is( familyMembers.size() ) );
|
List<Person> members = family.getMembers();
|
||||||
for ( Person person : members ) {
|
assertThat( members.size(), is( familyMembers.size() ) );
|
||||||
if ( person instanceof Man ) {
|
for ( Person person : members ) {
|
||||||
assertThat( ( (Man) person ).getHobby(), is( john.getHobby() ) );
|
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 Woman ) {
|
||||||
}
|
assertThat( ( (Woman) person ).getJob(), is( jane.getJob() ) );
|
||||||
else if ( person instanceof Child ) {
|
}
|
||||||
if ( person.getName().equals( "Susan" ) ) {
|
else if ( person instanceof Child ) {
|
||||||
assertThat( ( (Child) person ).getFavouriteToy(), is( susan.getFavouriteToy() ) );
|
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")
|
@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