discriminator work
- Handle discriminator as Fetch for entity ResultGraphNodes. This allows us to make the distinction about whether to handle the discriminator as `Class` or as its "underlying" type when selecting it. Fetches return the underlying type. DomainResults return `Class`, or String for entity-named entity mappings
This commit is contained in:
parent
fb651ef07d
commit
524b2982cf
|
@ -36,37 +36,20 @@ public class EntityResultImpl implements EntityResult {
|
|||
private final NavigablePath navigablePath;
|
||||
private final EntityValuedModelPart entityValuedModelPart;
|
||||
|
||||
private final DomainResult identifierResult;
|
||||
private final Fetch discriminatorFetch;
|
||||
private final DomainResult<?> identifierResult;
|
||||
private final BasicFetch<?> discriminatorFetch;
|
||||
private final List<Fetch> fetches;
|
||||
|
||||
private final String resultAlias;
|
||||
private final LockMode lockMode;
|
||||
|
||||
public EntityResultImpl(
|
||||
NavigablePath navigablePath,
|
||||
EntityValuedModelPart entityValuedModelPart,
|
||||
String resultAlias,
|
||||
LockMode lockMode,
|
||||
BasicFetch<?> discriminatorFetch,
|
||||
DomainResultCreationState creationState) {
|
||||
this(
|
||||
navigablePath,
|
||||
entityValuedModelPart,
|
||||
resultAlias,
|
||||
lockMode,
|
||||
entityResult -> discriminatorFetch,
|
||||
creationState
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings( { "PointlessNullCheck" } )
|
||||
public EntityResultImpl(
|
||||
NavigablePath navigablePath,
|
||||
EntityValuedModelPart entityValuedModelPart,
|
||||
String resultAlias,
|
||||
LockMode lockMode,
|
||||
Function<EntityResultImpl, BasicFetch> discriminatorFetchBuilder,
|
||||
Function<EntityResultImpl, BasicFetch<?>> discriminatorFetchBuilder,
|
||||
DomainResultCreationState creationState) {
|
||||
this.navigablePath = navigablePath;
|
||||
this.entityValuedModelPart = entityValuedModelPart;
|
||||
|
@ -151,7 +134,7 @@ public class EntityResultImpl implements EntityResult {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DomainResultAssembler createResultAssembler(AssemblerCreationState creationState) {
|
||||
public DomainResultAssembler<?> createResultAssembler(AssemblerCreationState creationState) {
|
||||
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
|
||||
getNavigablePath(),
|
||||
getReferencedModePart(),
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
|
|||
import org.hibernate.sql.results.graph.AbstractFetchParent;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
import org.hibernate.sql.results.graph.basic.BasicFetch;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
import static org.hibernate.query.results.ResultsHelper.attributeName;
|
||||
|
@ -36,9 +36,9 @@ import static org.hibernate.query.results.ResultsHelper.attributeName;
|
|||
*/
|
||||
public abstract class AbstractEntityResultGraphNode extends AbstractFetchParent implements EntityResultGraphNode {
|
||||
private final EntityValuedModelPart referencedModelPart;
|
||||
private final DomainResult identifierResult;
|
||||
private final Fetch discriminatorFetch;
|
||||
private final DomainResult versionResult;
|
||||
private final DomainResult<?> identifierResult;
|
||||
private final BasicFetch<?> discriminatorFetch;
|
||||
private final DomainResult<?> versionResult;
|
||||
private final DomainResult<Object> rowIdResult;
|
||||
|
||||
private final EntityMappingType targetType;
|
||||
|
@ -208,7 +208,7 @@ public abstract class AbstractEntityResultGraphNode extends AbstractFetchParent
|
|||
return identifierResult;
|
||||
}
|
||||
|
||||
public Fetch getDiscriminatorFetch() {
|
||||
public BasicFetch<?> getDiscriminatorFetch() {
|
||||
return discriminatorFetch;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import org.hibernate.LockMode;
|
|||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
import org.hibernate.sql.results.graph.basic.BasicFetch;
|
||||
import org.hibernate.sql.results.graph.entity.AbstractEntityInitializer;
|
||||
import org.hibernate.sql.results.graph.entity.EntityResultGraphNode;
|
||||
|
||||
|
@ -27,7 +27,7 @@ public class EntityResultInitializer extends AbstractEntityInitializer {
|
|||
NavigablePath navigablePath,
|
||||
LockMode lockMode,
|
||||
DomainResult identifierResult,
|
||||
Fetch discriminatorResult,
|
||||
BasicFetch<?> discriminatorFetch,
|
||||
DomainResult versionResult,
|
||||
DomainResult<Object> rowIdResult,
|
||||
AssemblerCreationState creationState) {
|
||||
|
@ -36,7 +36,7 @@ public class EntityResultInitializer extends AbstractEntityInitializer {
|
|||
navigablePath,
|
||||
lockMode,
|
||||
identifierResult,
|
||||
discriminatorResult,
|
||||
discriminatorFetch,
|
||||
versionResult,
|
||||
rowIdResult,
|
||||
creationState
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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.discriminator.joined;
|
||||
|
||||
import javax.persistence.Tuple;
|
||||
|
||||
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.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/orm/test/discriminator/joined/JoinedSubclassInheritance.hbm.xml"
|
||||
)
|
||||
@SessionFactory
|
||||
public class DiscriminatorQueryUsageTests {
|
||||
@Test
|
||||
public void testUsageAsSelection(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
final Tuple resultTuple = session
|
||||
.createQuery( "select p.id as id, type(p) as type from ParentEntity p", Tuple.class )
|
||||
.uniqueResult();
|
||||
|
||||
Assertions.assertThat( resultTuple.get( "id" ) ).isEqualTo( 1 );
|
||||
Assertions.assertThat( resultTuple.get( "type" ) ).isEqualTo( ChildEntity.class );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUsageAsPredicate(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
final Integer id = session.createQuery( "select p.id from ParentEntity p where type(p) = ChildEntity", Integer.class ).uniqueResult();
|
||||
Assertions.assertThat( id ).isEqualTo( 1 );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUsageAsPredicateOfUnderlyingType(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
final Integer id = session.createQuery( "select p.id from ParentEntity p where type(p) = 'ce'", Integer.class ).uniqueResult();
|
||||
Assertions.assertThat( id ).isEqualTo( 1 );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUsageAsPredicateWithParam(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
final Integer id = session.createQuery( "select p.id from ParentEntity p where type(p) = :type", Integer.class )
|
||||
.setParameter( "type", ChildEntity.class )
|
||||
.uniqueResult();
|
||||
Assertions.assertThat( id ).isEqualTo( 1 );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUsageAsPredicateWithParamOfUnderlyingType(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
final Integer id = session.createQuery( "select p.id from ParentEntity p where type(p) = :type", Integer.class )
|
||||
.setParameter( "type", "ce" )
|
||||
.uniqueResult();
|
||||
Assertions.assertThat( id ).isEqualTo( 1 );
|
||||
} );
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void createTestData(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> session.save( new ChildEntity( 1, "Child" ) ) );
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void dropTestData(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
session.createQuery( "delete from ParentEntity" ).executeUpdate();
|
||||
} );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue