initial work on joined inheritance, implemented root queries

This commit is contained in:
Andrea Boriero 2019-11-04 09:08:49 +00:00
parent 7120b8bd40
commit bef4fc1fde
9 changed files with 369 additions and 71 deletions

View File

@ -108,7 +108,10 @@ import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.ForUpdateFragment; import org.hibernate.sql.ForUpdateFragment;
import org.hibernate.sql.JoinFragment; import org.hibernate.sql.JoinFragment;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAstWalker;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.tool.hbm2ddl.SchemaUpdate; import org.hibernate.tool.hbm2ddl.SchemaUpdate;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl; import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl; import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
@ -1782,6 +1785,34 @@ public abstract class Dialect implements ConversionContext {
return new ANSICaseFragment(); return new ANSICaseFragment();
} }
public void visitCaseSearchedExpression(
CaseSearchedExpression caseSearchedExpression,
StringBuilder sqlBuffer,
SqlAstWalker sqlAstWalker) {
sqlBuffer.append( "case " );
for ( CaseSearchedExpression.WhenFragment whenFragment : caseSearchedExpression.getWhenFragments() ) {
sqlBuffer.append( " when " );
whenFragment.getPredicate().accept( sqlAstWalker );
sqlBuffer.append( " then " );
whenFragment.getResult().accept( sqlAstWalker );
}
Expression otherwise = caseSearchedExpression.getOtherwise();
if ( otherwise != null ) {
sqlBuffer.append( " else " );
otherwise.accept( sqlAstWalker );
}
sqlBuffer.append( " end" );
String columnExpression = caseSearchedExpression.getColumnExpression();
if ( columnExpression != null ) {
sqlBuffer.append( " as " ).append( columnExpression );
}
}
/** /**
* The fragment used to insert a row without specifying any column values. * The fragment used to insert a row without specifying any column values.
* This is not possible on some databases. * This is not possible on some databases.

View File

@ -34,21 +34,28 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class EntityDiscriminatorMappingImpl implements EntityDiscriminatorMapping { public class EntityDiscriminatorMappingImpl implements EntityDiscriminatorMapping {
private final EntityPersister entityDescriptor; private final EntityPersister entityPersister;
private final String tableExpression; private final String tableExpression;
private final String mappedColumnExpression; private String mappedColumnExpression;
private final BasicType mappingType; private final BasicType mappingType;
public EntityDiscriminatorMappingImpl( public EntityDiscriminatorMappingImpl(
EntityPersister entityDescriptor, EntityPersister entityPersister,
String tableExpression, String tableExpression,
String mappedColumnExpression, String mappedColumnExpression,
BasicType mappingType) { BasicType mappingType) {
this.entityDescriptor = entityDescriptor; this( entityPersister, tableExpression, mappingType );
this.tableExpression = tableExpression;
this.mappedColumnExpression = mappedColumnExpression; this.mappedColumnExpression = mappedColumnExpression;
}
public EntityDiscriminatorMappingImpl(
EntityPersister entityPersister,
String tableExpression,
BasicType mappingType) {
this.entityPersister = entityPersister;
this.tableExpression = tableExpression;
this.mappingType = mappingType; this.mappingType = mappingType;
} }
@ -132,7 +139,7 @@ public class EntityDiscriminatorMappingImpl implements EntityDiscriminatorMappin
); );
} }
private SqlSelection resolveSqlSelection(TableGroup tableGroup, DomainResultCreationState creationState) { protected SqlSelection resolveSqlSelection(TableGroup tableGroup, DomainResultCreationState creationState) {
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState().getSqlExpressionResolver(); final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState().getSqlExpressionResolver();
final TableReference tableReference = tableGroup.resolveTableReference( getContainingTableExpression() ); final TableReference tableReference = tableGroup.resolveTableReference( getContainingTableExpression() );
@ -169,4 +176,8 @@ public class EntityDiscriminatorMappingImpl implements EntityDiscriminatorMappin
public JdbcMapping getJdbcMapping() { public JdbcMapping getJdbcMapping() {
return mappingType.getJdbcMapping(); return mappingType.getJdbcMapping();
} }
protected EntityPersister getEntityPersister(){
return entityPersister;
}
} }

View File

@ -0,0 +1,49 @@
/*
* 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.metamodel.mapping.internal;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.results.spi.DomainResultCreationState;
import org.hibernate.type.BasicType;
/**
* @author Andrea Boriero
*/
public class JoinedSubclassDiscriminatorMappingImpl extends EntityDiscriminatorMappingImpl {
private final CaseSearchedExpression caseSearchedExpression;
public JoinedSubclassDiscriminatorMappingImpl(
EntityPersister entityDescriptor,
String tableExpression,
CaseSearchedExpression caseSearchedExpression,
BasicType mappingType) {
super( entityDescriptor, tableExpression, mappingType );
this.caseSearchedExpression = caseSearchedExpression;
}
@Override
protected SqlSelection resolveSqlSelection(TableGroup tableGroup, DomainResultCreationState creationState) {
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState()
.getSqlExpressionResolver();
return expressionResolver.resolveSqlSelection(
expressionResolver.resolveSqlExpression(
getMappedColumnExpression(),
sqlAstProcessingState -> caseSearchedExpression
),
getMappedTypeDescriptor().getMappedJavaTypeDescriptor(),
creationState.getSqlAstCreationState().getCreationContext().getDomainModel().getTypeConfiguration()
);
}
}

View File

@ -17,6 +17,7 @@ import java.util.Set;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.QueryException; import org.hibernate.QueryException;
import org.hibernate.boot.model.relational.Database; import org.hibernate.boot.model.relational.Database;
@ -42,14 +43,35 @@ import org.hibernate.mapping.Selectable;
import org.hibernate.mapping.Subclass; import org.hibernate.mapping.Subclass;
import org.hibernate.mapping.Table; import org.hibernate.mapping.Table;
import org.hibernate.mapping.Value; import org.hibernate.mapping.Value;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.internal.JoinedSubclassDiscriminatorMappingImpl;
import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.sql.CaseFragment; import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.InFragment; import org.hibernate.sql.InFragment;
import org.hibernate.sql.Insert; import org.hibernate.sql.Insert;
import org.hibernate.sql.SelectFragment; import org.hibernate.sql.SelectFragment;
import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.JoinType;
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
import org.hibernate.sql.ast.tree.expression.ColumnReference;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.sql.ast.tree.from.TableReferenceJoin;
import org.hibernate.sql.ast.tree.predicate.NullnessPredicate;
import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.sql.results.internal.domain.entity.JoinedSubclassResultImpl;
import org.hibernate.sql.results.spi.DomainResult;
import org.hibernate.sql.results.spi.DomainResultCreationState;
import org.hibernate.sql.results.spi.Fetchable; import org.hibernate.sql.results.spi.Fetchable;
import org.hibernate.type.BasicType;
import org.hibernate.type.DiscriminatorType; import org.hibernate.type.DiscriminatorType;
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.StringType;
import org.hibernate.type.Type; import org.hibernate.type.Type;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
@ -130,9 +152,8 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
private final boolean[] isNullableTable; private final boolean[] isNullableTable;
private final boolean[] isInverseTable; private final boolean[] isInverseTable;
// private final String tableName; private final Map<String, String> discriminatorValuesByTableName;
// private final Map<String, String> subclassNameByTableName;
// private final String superClassTableName;
//INITIALIZATION: //INITIALIZATION:
@ -211,16 +232,6 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
throw new MappingException( "optimistic-lock=all|dirty not supported for joined-subclass mappings [" + getEntityName() + "]" ); throw new MappingException( "optimistic-lock=all|dirty not supported for joined-subclass mappings [" + getEntityName() + "]" );
} }
// final PersistentClass superclass = persistentClass.getSuperclass();
// if ( superclass != null ) {
// superClassTableName = determineTableName( superclass.getTable(), jdbcEnvironment );
// }
// else {
// superClassTableName = null;
// }
//
// tableName = determineTableName( persistentClass.getTable(), jdbcEnvironment );
//MULTITABLES //MULTITABLES
final int idColumnSpan = getIdentifierColumnSpan(); final int idColumnSpan = getIdentifierColumnSpan();
@ -513,6 +524,10 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
subclassClosure[subclassSpan - 1] = getEntityName(); subclassClosure[subclassSpan - 1] = getEntityName();
if ( persistentClass.isPolymorphic() ) { if ( persistentClass.isPolymorphic() ) {
subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() ); subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() );
discriminatorValuesByTableName = new HashMap<>( subclassSpan + 1 );
subclassNameByTableName = new HashMap<>( subclassSpan + 1);
discriminatorValuesByTableName.put( persistentClass.getTable().getName(), discriminatorSQLString);
discriminatorValues = new String[subclassSpan]; discriminatorValues = new String[subclassSpan];
discriminatorValues[subclassSpan - 1] = discriminatorSQLString; discriminatorValues[subclassSpan - 1] = discriminatorSQLString;
notNullColumnTableNumbers = new int[subclassSpan]; notNullColumnTableNumbers = new int[subclassSpan];
@ -529,6 +544,8 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
notNullColumnNames[subclassSpan - 1] = subclassTableKeyColumnClosure[id][0]; //( (Column) model.getTable().getPrimaryKey().getColumnIterator().next() ).getName(); notNullColumnNames[subclassSpan - 1] = subclassTableKeyColumnClosure[id][0]; //( (Column) model.getTable().getPrimaryKey().getColumnIterator().next() ).getName();
} }
else { else {
subclassNameByTableName = Collections.EMPTY_MAP;
discriminatorValuesByTableName = Collections.EMPTY_MAP;
discriminatorValues = null; discriminatorValues = null;
notNullColumnTableNumbers = null; notNullColumnTableNumbers = null;
notNullColumnNames = null; notNullColumnNames = null;
@ -539,6 +556,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
while ( iter.hasNext() ) { while ( iter.hasNext() ) {
Subclass sc = (Subclass) iter.next(); Subclass sc = (Subclass) iter.next();
subclassClosure[k] = sc.getEntityName(); subclassClosure[k] = sc.getEntityName();
subclassNameByTableName.put( sc.getTable().getName(), sc.getClassName() );
try { try {
if ( persistentClass.isPolymorphic() ) { if ( persistentClass.isPolymorphic() ) {
final Object discriminatorValue; final Object discriminatorValue;
@ -567,7 +585,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
// "foo.class = Bar" works in HQL // "foo.class = Bar" works in HQL
discriminatorValue = sc.getSubclassId(); discriminatorValue = sc.getSubclassId();
} }
discriminatorValuesByTableName.put( sc.getTable().getName(), discriminatorValue.toString() );
subclassesByDiscriminatorValue.put( discriminatorValue, sc.getEntityName() ); subclassesByDiscriminatorValue.put( discriminatorValue, sc.getEntityName() );
discriminatorValues[k] = discriminatorValue.toString(); discriminatorValues[k] = discriminatorValue.toString();
int id = getTableId( int id = getTableId(
@ -1127,24 +1145,6 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
throw new HibernateException( "Could not locate table which owns column [" + columnName + "] referenced in order-by mapping" ); throw new HibernateException( "Could not locate table which owns column [" + columnName + "] referenced in order-by mapping" );
} }
@Override
protected void buildDiscriminatorMapping() {
if ( hasSubclasses() ) {
super.buildDiscriminatorMapping();
}
}
@Override
protected List<Fetchable> getStaticFetchableList() {
if ( staticFetchableList == null ) {
staticFetchableList = new ArrayList<>( getAttributeMappings().size() );
visitAttributeMappings( attributeMapping -> staticFetchableList.add( (Fetchable) attributeMapping ) );
}
return staticFetchableList;
}
@Override @Override
public FilterAliasGenerator getFilterAliasGenerator(String rootAlias) { public FilterAliasGenerator getFilterAliasGenerator(String rootAlias) {
return new DynamicFilterAliasGenerator(subclassTableNameClosure, rootAlias); return new DynamicFilterAliasGenerator(subclassTableNameClosure, rootAlias);
@ -1154,4 +1154,117 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
public boolean canOmitSuperclassTableJoin() { public boolean canOmitSuperclassTableJoin() {
return true; return true;
} }
@Override
public <T> DomainResult<T> createDomainResult(
NavigablePath navigablePath,
TableGroup tableGroup,
String resultVariable,
DomainResultCreationState creationState) {
if ( hasSubclasses() ) {
//noinspection unchecked
return new JoinedSubclassResultImpl( navigablePath, this, resultVariable, creationState );
}
else {
return super.createDomainResult( navigablePath, tableGroup, resultVariable, creationState );
}
}
@Override
public TableGroup createRootTableGroup(
NavigablePath navigablePath,
String explicitSourceAlias,
JoinType tableReferenceJoinType,
LockMode lockMode,
SqlAliasBaseGenerator aliasBaseGenerator,
SqlExpressionResolver sqlExpressionResolver,
Supplier<Consumer<Predicate>> additionalPredicateCollectorAccess,
SqlAstCreationContext creationContext) {
if ( hasSubclasses() ) {
tableReferenceJoinType = JoinType.LEFT;
}
return super.createRootTableGroup(
navigablePath,
explicitSourceAlias,
tableReferenceJoinType,
lockMode,
aliasBaseGenerator,
sqlExpressionResolver,
additionalPredicateCollectorAccess,
creationContext
);
}
public EntityDiscriminatorMapping getDiscriminatorMapping(TableGroup tableGroup) {
return new JoinedSubclassDiscriminatorMappingImpl(
this,
getRootTableName(),
getCaseSearchedExpression( tableGroup ),
(BasicType) getDiscriminatorType()
);
}
private CaseSearchedExpression getCaseSearchedExpression(TableGroup entityTableGroup) {
final TableReference primaryTableReference = entityTableGroup.getPrimaryTableReference();
final List<TableReferenceJoin> tableReferenceJoins = entityTableGroup.getTableReferenceJoins();
final BasicType discriminatorType = (BasicType) getDiscriminatorType();
final CaseSearchedExpression caseSearchedExpression = new CaseSearchedExpression( discriminatorType );
caseSearchedExpression.setColumnExpression( getDiscriminatorColumnName() );
tableReferenceJoins.forEach(
tableReferenceJoin -> {
final TableReference joinedTableReference = tableReferenceJoin.getJoinedTableReference();
final EntityPersister entityDescriptor = getFactory().getMetamodel()
.findEntityDescriptor( subclassNameByTableName.get( joinedTableReference.getTableExpression() ) );
if ( entityDescriptor instanceof JoinedSubclassEntityPersister ) {
addWhen(
caseSearchedExpression,
joinedTableReference,
( (JoinedSubclassEntityPersister) entityDescriptor )
.getIdentifierColumnReferenceForCaseExpression( joinedTableReference ),
discriminatorType
);
}
}
);
addWhen(
caseSearchedExpression,
primaryTableReference,
getIdentifierColumnReferenceForCaseExpression( primaryTableReference ),
discriminatorType
);
return caseSearchedExpression;
}
private void addWhen(
CaseSearchedExpression caseSearchedExpression,
TableReference table,
ColumnReference identifierColumnReference,
BasicType resultType) {
final Predicate predicate = new NullnessPredicate( identifierColumnReference, true );
final Expression expression =
new QueryLiteral<>(
discriminatorValuesByTableName.get( table.getTableExpression() ),
resultType,
Clause.SELECT
);
caseSearchedExpression.when( predicate, expression );
}
private ColumnReference getIdentifierColumnReferenceForCaseExpression(TableReference primaryTableReference) {
List<JdbcMapping> jdbcMappings = getIdentifierMapping().getJdbcMappings( getFactory().getTypeConfiguration() );
JdbcMapping jdbcMapping = jdbcMappings.get( 0 );
return new ColumnReference(
primaryTableReference.getIdentificationVariable(),
getIdentifierColumnNames()[0],
jdbcMapping,
getFactory()
);
}
} }

View File

@ -11,6 +11,7 @@ import java.util.List;
import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.SortOrder; import org.hibernate.SortOrder;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.collections.Stack; import org.hibernate.internal.util.collections.Stack;
@ -83,9 +84,12 @@ public abstract class AbstractSqlAstWalker
private final Stack<Clause> clauseStack = new StandardStack<>(); private final Stack<Clause> clauseStack = new StandardStack<>();
private final Dialect dialect;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
protected AbstractSqlAstWalker(SessionFactoryImplementor sessionFactory) { protected AbstractSqlAstWalker(SessionFactoryImplementor sessionFactory) {
this.sessionFactory = sessionFactory; this.sessionFactory = sessionFactory;
this.dialect = sessionFactory.getJdbcServices().getDialect();
} }
@ -426,9 +430,7 @@ public abstract class AbstractSqlAstWalker
@Override @Override
public void visitSqlSelectionExpression(SqlSelectionExpression expression) { public void visitSqlSelectionExpression(SqlSelectionExpression expression) {
final boolean useSelectionPosition = getSessionFactory().getJdbcServices() final boolean useSelectionPosition = dialect.replaceResultVariableInOrderByClauseWithPosition();
.getDialect()
.replaceResultVariableInOrderByClauseWithPosition();
if ( useSelectionPosition ) { if ( useSelectionPosition ) {
appendSql( Integer.toString( expression.getSelection().getJdbcResultSetIndex() ) ); appendSql( Integer.toString( expression.getSelection().getJdbcResultSetIndex() ) );
@ -740,19 +742,7 @@ public abstract class AbstractSqlAstWalker
@Override @Override
public void visitCaseSearchedExpression(CaseSearchedExpression caseSearchedExpression) { public void visitCaseSearchedExpression(CaseSearchedExpression caseSearchedExpression) {
appendSql( "case " ); dialect.visitCaseSearchedExpression( caseSearchedExpression, sqlBuffer, this );
for ( CaseSearchedExpression.WhenFragment whenFragment : caseSearchedExpression.getWhenFragments() ) {
appendSql( " when " );
whenFragment.getPredicate().accept( this );
appendSql( " then " );
whenFragment.getResult().accept( this );
}
appendSql( " else " );
caseSearchedExpression.getOtherwise().accept( this );
appendSql( " end" );
} }
@Override @Override
@ -843,7 +833,7 @@ public abstract class AbstractSqlAstWalker
appendSql( appendSql(
literalFormatter.toJdbcLiteral( literalFormatter.toJdbcLiteral(
queryLiteral.getValue(), queryLiteral.getValue(),
sessionFactory.getJdbcServices().getJdbcEnvironment().getDialect(), dialect,
null null
) )
); );

View File

@ -10,25 +10,39 @@ package org.hibernate.sql.ast.tree.expression;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.mapping.MappingModelExpressable; import org.hibernate.metamodel.mapping.MappingModelExpressable;
import org.hibernate.query.sqm.sql.internal.DomainResultProducer; import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
import org.hibernate.sql.ast.spi.SqlAstWalker; import org.hibernate.sql.ast.spi.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.ast.tree.predicate.Predicate; import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.sql.results.internal.SqlSelectionImpl;
import org.hibernate.sql.results.internal.domain.basic.BasicResult;
import org.hibernate.sql.results.spi.DomainResult; import org.hibernate.sql.results.spi.DomainResult;
import org.hibernate.sql.results.spi.DomainResultCreationState; import org.hibernate.sql.results.spi.DomainResultCreationState;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class CaseSearchedExpression implements Expression, DomainResultProducer { public class CaseSearchedExpression implements Expression, DomainResultProducer {
private final MappingModelExpressable type; private final BasicType type;
private List<WhenFragment> whenFragments = new ArrayList<>(); private List<WhenFragment> whenFragments = new ArrayList<>();
private Expression otherwise; private Expression otherwise;
private String columnExpression;
public CaseSearchedExpression(MappingModelExpressable type) { public CaseSearchedExpression(MappingModelExpressable type) {
this.type = type; this.type = (BasicType) type;
}
public void setColumnExpression(String columnExpression) {
this.columnExpression = columnExpression;
}
public String getColumnExpression(){
return columnExpression;
} }
public List<WhenFragment> getWhenFragments() { public List<WhenFragment> getWhenFragments() {
@ -52,17 +66,36 @@ public class CaseSearchedExpression implements Expression, DomainResultProducer
public DomainResult createDomainResult( public DomainResult createDomainResult(
String resultVariable, String resultVariable,
DomainResultCreationState creationState) { DomainResultCreationState creationState) {
throw new NotYetImplementedFor6Exception( getClass() );
// return new BasicResultImpl( final SqlSelection sqlSelection = creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
// resultVariable, this,
// creationState.getSqlExpressionResolver().resolveSqlSelection( type.getExpressableJavaTypeDescriptor(),
// this, creationState.getSqlAstCreationState()
// getType().getJavaTypeDescriptor(), .getCreationContext()
// creationState.getSqlAstCreationState().getCreationContext().getDomainModel().getTypeConfiguration() .getSessionFactory()
// ), .getTypeConfiguration()
// getType() );
// );
//noinspection unchecked
return new BasicResult(
sqlSelection.getValuesArrayPosition(),
resultVariable,
type.getExpressableJavaTypeDescriptor()
);
}
@Override
public SqlSelection createSqlSelection(
int jdbcPosition,
int valuesArrayPosition,
JavaTypeDescriptor javaTypeDescriptor,
TypeConfiguration typeConfiguration) {
return new SqlSelectionImpl(
jdbcPosition,
valuesArrayPosition,
this,
type.getJdbcMapping()
);
} }
@Override @Override

View File

@ -64,8 +64,9 @@ public abstract class AbstractEntityResultNode extends AbstractFetchParent imple
creationState creationState
); );
if ( entityDescriptor.getDiscriminatorMapping() != null ) { final EntityDiscriminatorMapping discriminatorMapping = getDiscriminatorMapping( entityDescriptor, entityTableGroup );
discriminatorResult = entityDescriptor.getDiscriminatorMapping().createDomainResult( if ( discriminatorMapping != null ) {
discriminatorResult = discriminatorMapping.createDomainResult(
navigablePath.append( EntityDiscriminatorMapping.ROLE_NAME ), navigablePath.append( EntityDiscriminatorMapping.ROLE_NAME ),
entityTableGroup, entityTableGroup,
null, null,
@ -90,6 +91,12 @@ public abstract class AbstractEntityResultNode extends AbstractFetchParent imple
} }
} }
protected EntityDiscriminatorMapping getDiscriminatorMapping(
EntityMappingType entityDescriptor,
TableGroup entityTableGroup) {
return entityDescriptor.getDiscriminatorMapping();
}
@Override @Override
public EntityValuedModelPart getReferencedMappingContainer() { public EntityValuedModelPart getReferencedMappingContainer() {
return getEntityValuedModelPart(); return getEntityValuedModelPart();

View File

@ -0,0 +1,65 @@
/*
* 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.sql.results.internal.domain.entity;
import java.util.function.Consumer;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
import org.hibernate.persister.entity.JoinedSubclassEntityPersister;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.results.spi.AssemblerCreationState;
import org.hibernate.sql.results.spi.DomainResultAssembler;
import org.hibernate.sql.results.spi.DomainResultCreationState;
/**
* @author Andrea Boriero
*/
public class JoinedSubclassResultImpl extends EntityResultImpl {
public JoinedSubclassResultImpl(
NavigablePath navigablePath,
EntityValuedModelPart entityValuedModelPart,
String resultVariable,
DomainResultCreationState creationState) {
super( navigablePath, entityValuedModelPart, resultVariable, creationState );
}
@Override
public DomainResultAssembler createResultAssembler(
Consumer initializerCollector,
AssemblerCreationState creationState) {
// todo (6.0) : seems like here is where we ought to determine the SQL selection mappings
final EntityRootInitializer initializer = new EntityRootInitializer(
this,
getNavigablePath(),
getLockMode(),
getIdentifierResult(),
getDiscriminatorResult(),
getVersionResult(),
initializerCollector,
creationState
);
return new EntityAssembler( getResultJavaTypeDescriptor(), initializer );
}
@Override
protected EntityDiscriminatorMapping getDiscriminatorMapping(
EntityMappingType entityDescriptor,
TableGroup entityTableGroup) {
final JoinedSubclassEntityPersister joinedSubclassEntityPersister = (JoinedSubclassEntityPersister) entityDescriptor;
if ( joinedSubclassEntityPersister.hasSubclasses() ) {
return joinedSubclassEntityPersister.getDiscriminatorMapping( entityTableGroup );
}
else {
return null;
}
}
}

View File

@ -77,7 +77,6 @@ public class JoinedInheritanceTest {
} }
@Test @Test
@FailureExpected
public void rootQueryExecutionTest(SessionFactoryScope scope) { public void rootQueryExecutionTest(SessionFactoryScope scope) {
scope.inTransaction( scope.inTransaction(
session -> { session -> {