improve discriminator handling
- use fetch/result as the distinction for whether to select Class / entity-name or the "underlying type" value for discriminator. The only time we'd have a DomainResult for the discriminator is for Query where the type is selected; all other times want the underlying type
This commit is contained in:
parent
aaba4767fe
commit
6f60cd8918
|
@ -9,8 +9,9 @@ package org.hibernate.metamodel.mapping;
|
|||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
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.FetchOptions;
|
||||
|
@ -40,6 +41,18 @@ public interface EntityDiscriminatorMapping extends VirtualModelPart, BasicValue
|
|||
|
||||
String getConcreteEntityNameForDiscriminatorValue(Object value);
|
||||
|
||||
/**
|
||||
* Create the appropriate SQL expression for this discriminator
|
||||
*
|
||||
* @param jdbcMappingToUse The JDBC mapping to use. This allows opting between
|
||||
* the "domain result type" (aka Class) and the "underlying type" (Integer, String, etc)
|
||||
*/
|
||||
Expression resolveSqlExpression(
|
||||
NavigablePath navigablePath,
|
||||
JdbcMapping jdbcMappingToUse,
|
||||
TableGroup tableGroup,
|
||||
SqlAstCreationState creationState);
|
||||
|
||||
@Override
|
||||
BasicFetch generateFetch(
|
||||
FetchParent fetchParent,
|
||||
|
|
|
@ -92,6 +92,10 @@ public interface EntityMappingType extends ManagedMappingType, EntityValuedModel
|
|||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Inheritance
|
||||
|
||||
default boolean hasSubclasses() {
|
||||
return getEntityPersister().getEntityMetamodel().hasSubclasses();
|
||||
}
|
||||
|
||||
default AttributeMapping findDeclaredAttributeMapping(String name) {
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
// or ?
|
||||
|
@ -144,16 +148,16 @@ public interface EntityMappingType extends ManagedMappingType, EntityValuedModel
|
|||
|
||||
EntityIdentifierMapping getIdentifierMapping();
|
||||
|
||||
EntityDiscriminatorMapping getDiscriminatorMapping();
|
||||
Object getDiscriminatorValue();
|
||||
String getSubclassForDiscriminatorValue(Object value);
|
||||
|
||||
EntityVersionMapping getVersionMapping();
|
||||
|
||||
EntityRowIdMapping getRowIdMapping();
|
||||
|
||||
EntityDiscriminatorMapping getDiscriminatorMapping();
|
||||
|
||||
EntityDiscriminatorMapping getDiscriminatorMapping(TableGroup tableGroup);
|
||||
|
||||
NaturalIdMapping getNaturalIdMapping();
|
||||
|
||||
EntityRowIdMapping getRowIdMapping();
|
||||
|
||||
/**
|
||||
* Visit the mappings, but limited to just attributes defined
|
||||
* in the targetType or its super-type(s) if any.
|
||||
|
@ -195,6 +199,10 @@ public interface EntityMappingType extends ManagedMappingType, EntityValuedModel
|
|||
return tableGroup.getPrimaryTableReference();
|
||||
}
|
||||
|
||||
default boolean isAbstract() {
|
||||
return getEntityPersister().getEntityMetamodel().isAbstract();
|
||||
}
|
||||
|
||||
interface ConstraintOrderedTableConsumer {
|
||||
void consume(String tableExpression, Supplier<Consumer<SelectableConsumer>> tableKeyColumnVisitationSupplier);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,397 @@
|
|||
/*
|
||||
* 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 java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.mapping.IndexedConsumer;
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.MappingType;
|
||||
import org.hibernate.metamodel.mapping.SelectableConsumer;
|
||||
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.persister.entity.DiscriminatorType;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
import org.hibernate.sql.results.graph.basic.BasicFetch;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import static org.hibernate.metamodel.RepresentationMode.MAP;
|
||||
|
||||
/**
|
||||
* @implNote `discriminatorType` represents the mapping to Class, whereas `discriminatorType.getUnderlyingType()`
|
||||
* represents the "raw" JDBC mapping (String, Integer, etc)
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractDiscriminatorMapping implements EntityDiscriminatorMapping {
|
||||
private final NavigableRole role;
|
||||
private final JdbcMapping jdbcMapping;
|
||||
|
||||
private final EntityPersister entityDescriptor;
|
||||
private final DiscriminatorType<?> discriminatorType;
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
private final DomainResultConverter<?> domainResultConverter;
|
||||
|
||||
public AbstractDiscriminatorMapping(
|
||||
JdbcMapping jdbcMapping,
|
||||
EntityPersister entityDescriptor,
|
||||
DiscriminatorType<?> discriminatorType,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
this.jdbcMapping = jdbcMapping;
|
||||
|
||||
this.entityDescriptor = entityDescriptor;
|
||||
this.discriminatorType = discriminatorType;
|
||||
|
||||
role = entityDescriptor.getNavigableRole().append( EntityDiscriminatorMapping.ROLE_NAME );
|
||||
sessionFactory = creationProcess.getCreationContext().getSessionFactory();
|
||||
|
||||
domainResultConverter = DomainResultConverter.create(
|
||||
entityDescriptor,
|
||||
this::getConcreteEntityNameForDiscriminatorValue,
|
||||
discriminatorType.getUnderlyingType(),
|
||||
sessionFactory
|
||||
);
|
||||
}
|
||||
|
||||
public EntityPersister getEntityDescriptor() {
|
||||
return entityDescriptor;
|
||||
}
|
||||
|
||||
public BasicType<?> getUnderlyingJdbcMappingType() {
|
||||
return discriminatorType.getUnderlyingType();
|
||||
}
|
||||
|
||||
public SessionFactoryImplementor getSessionFactory() {
|
||||
return sessionFactory;
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// EntityDiscriminatorMapping
|
||||
|
||||
@Override
|
||||
public NavigableRole getNavigableRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcMapping getJdbcMapping() {
|
||||
return jdbcMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConcreteEntityNameForDiscriminatorValue(Object value) {
|
||||
return getEntityDescriptor().getSubclassForDiscriminatorValue( value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityMappingType findContainingEntityMapping() {
|
||||
return entityDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingType getMappedType() {
|
||||
return getJdbcMapping();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor<?> getJavaTypeDescriptor() {
|
||||
return getJdbcMapping().getJavaTypeDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DomainResult<T> createDomainResult(
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
final SqlSelection sqlSelection = resolveSqlSelection( navigablePath, getUnderlyingJdbcMappingType(), tableGroup, creationState.getSqlAstCreationState() );
|
||||
|
||||
//noinspection unchecked
|
||||
return new BasicResult(
|
||||
sqlSelection.getValuesArrayPosition(),
|
||||
resultVariable,
|
||||
domainResultConverter.getDomainJavaDescriptor(),
|
||||
domainResultConverter,
|
||||
navigablePath
|
||||
);
|
||||
}
|
||||
|
||||
private SqlSelection resolveSqlSelection(
|
||||
NavigablePath navigablePath,
|
||||
JdbcMapping jdbcMappingToUse,
|
||||
TableGroup tableGroup,
|
||||
SqlAstCreationState creationState) {
|
||||
final SqlExpressionResolver expressionResolver = creationState.getSqlExpressionResolver();
|
||||
return expressionResolver.resolveSqlSelection(
|
||||
resolveSqlExpression( navigablePath, jdbcMappingToUse, tableGroup, creationState ),
|
||||
jdbcMappingToUse.getJavaTypeDescriptor(),
|
||||
creationState.getCreationContext().getDomainModel().getTypeConfiguration()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicFetch generateFetch(
|
||||
FetchParent fetchParent,
|
||||
NavigablePath fetchablePath,
|
||||
FetchTiming fetchTiming,
|
||||
boolean selected,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
|
||||
final TableGroup tableGroup = sqlAstCreationState.getFromClauseAccess().getTableGroup(
|
||||
fetchParent.getNavigablePath()
|
||||
);
|
||||
|
||||
assert tableGroup != null;
|
||||
|
||||
final SqlSelection sqlSelection = resolveSqlSelection( fetchablePath, getUnderlyingJdbcMappingType(), tableGroup, creationState.getSqlAstCreationState() );
|
||||
|
||||
return new BasicFetch<>(
|
||||
sqlSelection.getValuesArrayPosition(),
|
||||
fetchParent,
|
||||
fetchablePath,
|
||||
this,
|
||||
false,
|
||||
null,
|
||||
fetchTiming,
|
||||
creationState
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySqlSelections(
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
DomainResultCreationState creationState) {
|
||||
resolveSqlSelection( navigablePath, getUnderlyingJdbcMappingType(), tableGroup, creationState.getSqlAstCreationState() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySqlSelections(
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
DomainResultCreationState creationState,
|
||||
BiConsumer<SqlSelection, JdbcMapping> selectionConsumer) {
|
||||
selectionConsumer.accept(
|
||||
resolveSqlSelection( navigablePath, getUnderlyingJdbcMappingType(), tableGroup, creationState.getSqlAstCreationState() ),
|
||||
getJdbcMapping()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachDisassembledJdbcValue(
|
||||
Object value,
|
||||
Clause clause,
|
||||
int offset,
|
||||
JdbcValuesConsumer valuesConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
valuesConsumer.consume( offset, convertToRelational( value ), getJdbcMapping() );
|
||||
return getJdbcTypeCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
|
||||
action.accept( offset, getJdbcMapping() );
|
||||
return getJdbcTypeCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) {
|
||||
valueConsumer.consume( convertToRelational( domainValue ), this );
|
||||
}
|
||||
|
||||
private Object convertToRelational(Object domainValue) {
|
||||
if ( domainResultConverter != null ) {
|
||||
return domainResultConverter.toRelationalValue( domainValue );
|
||||
}
|
||||
return domainValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
||||
return convertToRelational( value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachJdbcValue(Object value, Clause clause, int offset, JdbcValuesConsumer valuesConsumer, SharedSessionContractImplementor session) {
|
||||
valuesConsumer.consume( offset, convertToRelational( value ), jdbcMapping );
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachSelectable(SelectableConsumer consumer) {
|
||||
return EntityDiscriminatorMapping.super.forEachSelectable( consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachSelectable(int offset, SelectableConsumer consumer) {
|
||||
return EntityDiscriminatorMapping.super.forEachSelectable( offset, consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachJdbcType(IndexedConsumer<JdbcMapping> action) {
|
||||
return EntityDiscriminatorMapping.super.forEachJdbcType( action );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Used to convert the underlying discriminator value into a Class (or String for entity-name)
|
||||
* reference for the entity type
|
||||
*/
|
||||
protected static class DomainResultConverter<R> implements BasicValueConverter<Object,R> {
|
||||
/**
|
||||
* Given a "raw" discriminator value, determines the corresponding concrete entity name
|
||||
*/
|
||||
private final Function<R,String> subtypeResolver;
|
||||
|
||||
/**
|
||||
* Given a concrete entity name, apply the conversion to determine the "domain result" value
|
||||
*
|
||||
* @apiNote This is only used when building a {@link DomainResult}
|
||||
*/
|
||||
private final Function<String, Object> entityNameHandler;
|
||||
|
||||
/**
|
||||
* Given a "domain form", apply the conversion to determine the corresponding relational value
|
||||
*/
|
||||
private final Function<Object, R> toRelationalConverter;
|
||||
|
||||
private final JavaTypeDescriptor<Object> domainJtd;
|
||||
private final JavaTypeDescriptor<R> relationalJtd;
|
||||
|
||||
public DomainResultConverter(
|
||||
Function<R,String> subtypeResolver,
|
||||
Function<String,Object> entityNameHandler,
|
||||
Function<Object,R> toRelationalConverter,
|
||||
JavaTypeDescriptor<Object> domainJtd,
|
||||
JavaTypeDescriptor<R> relationalJtd) {
|
||||
this.subtypeResolver = subtypeResolver;
|
||||
this.entityNameHandler = entityNameHandler;
|
||||
this.toRelationalConverter = toRelationalConverter;
|
||||
this.domainJtd = domainJtd;
|
||||
this.relationalJtd = relationalJtd;
|
||||
}
|
||||
|
||||
private static <R> DomainResultConverter<R> create(
|
||||
EntityPersister entityDescriptor,
|
||||
Function<R,String> subtypeResolver,
|
||||
BasicType underlyingDiscriminatorType,
|
||||
final SessionFactoryImplementor sessionFactory) {
|
||||
final TypeConfiguration typeConfiguration = sessionFactory.getDomainModel().getTypeConfiguration();
|
||||
final JavaTypeDescriptorRegistry jtdRegistry = typeConfiguration.getJavaTypeDescriptorRegistry();
|
||||
|
||||
final JavaTypeDescriptor<Object> domainJtd;
|
||||
final Function<String,Object> entityNameHandler;
|
||||
final Function<Object,Object> toRelationalConverter;
|
||||
|
||||
if ( entityDescriptor.getRepresentationStrategy().getMode() == MAP ) {
|
||||
// todo (6.0) : account for explicit entity-name which should also return String
|
||||
domainJtd = jtdRegistry.getDescriptor( String.class );
|
||||
entityNameHandler = (entityName) -> entityName;
|
||||
toRelationalConverter = (domainValue) -> {
|
||||
if ( domainValue instanceof Class ) {
|
||||
throw new IllegalArgumentException( "Illegal attempt to specify Class for discriminator for dynamic entity" );
|
||||
}
|
||||
if ( domainValue instanceof String ) {
|
||||
final String stringValue = (String) domainValue;
|
||||
// could be either an entity name or "underlying type" (e.g. mapped to VARCHAR)
|
||||
// - first we check as an entity name since that's a discrete set;
|
||||
// - handling as an "underlying type" value is handled in "otherwise"
|
||||
if ( entityDescriptor.isSubclassEntityName( stringValue ) ) {
|
||||
return entityDescriptor.getDiscriminatorValue();
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise we assume its an instance of the underlying type
|
||||
assert underlyingDiscriminatorType.getJavaTypeDescriptor().getJavaTypeClass().isInstance( domainJtd );
|
||||
return domainJtd;
|
||||
};
|
||||
}
|
||||
else {
|
||||
final ClassLoaderService cls = sessionFactory.getServiceRegistry().getService( ClassLoaderService.class );
|
||||
domainJtd = jtdRegistry.getDescriptor( Class.class );
|
||||
entityNameHandler = cls::classForName;
|
||||
toRelationalConverter = (domainValue) -> {
|
||||
if ( domainValue instanceof Class ) {
|
||||
final Class<?> classValue = (Class<?>) domainValue;
|
||||
final EntityMappingType concreteEntityMapping = sessionFactory.getRuntimeMetamodels().getEntityMappingType( classValue );
|
||||
return concreteEntityMapping.getDiscriminatorValue();
|
||||
}
|
||||
if ( domainValue instanceof String ) {
|
||||
final String stringValue = (String) domainValue;
|
||||
// could be either an entity name or "underlying type" (e.g. mapped to VARCHAR)
|
||||
// - first we check as an entity name since that's a discrete set;
|
||||
// - handling as an "underlying type" value is handled in "otherwise"
|
||||
if ( entityDescriptor.isSubclassEntityName( stringValue ) ) {
|
||||
return entityDescriptor.getDiscriminatorValue();
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise we assume its an instance of the underlying type
|
||||
assert underlyingDiscriminatorType.getJavaTypeDescriptor().getJavaTypeClass().isInstance( domainJtd );
|
||||
return domainJtd;
|
||||
};
|
||||
}
|
||||
|
||||
return new DomainResultConverter(
|
||||
subtypeResolver,
|
||||
entityNameHandler,
|
||||
toRelationalConverter,
|
||||
domainJtd,
|
||||
underlyingDiscriminatorType.getJavaTypeDescriptor()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toDomainValue(R relationalForm) {
|
||||
final String entityName = subtypeResolver.apply( relationalForm );
|
||||
return entityNameHandler.apply( entityName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public R toRelationalValue(Object domainForm) {
|
||||
// the domainForm could be any of Class (entity type), String (entity-name) or
|
||||
// underlying type (String, Integer, ..)
|
||||
|
||||
return toRelationalConverter.apply( domainForm );
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor<Object> getDomainJavaDescriptor() {
|
||||
return domainJtd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor<R> getRelationalJavaDescriptor() {
|
||||
return relationalJtd;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,152 +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.metamodel.mapping.internal;
|
||||
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.persister.entity.DiscriminatorType;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.Loadable;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
import org.hibernate.sql.results.graph.basic.BasicFetch;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
public abstract class AbstractEntityDiscriminatorMapping implements EntityDiscriminatorMapping {
|
||||
private final EntityPersister entityDescriptor;
|
||||
private final String tableExpression;
|
||||
private final String mappedColumnExpression;
|
||||
private final boolean isFormula;
|
||||
|
||||
private final DiscriminatorType<?> mappingType;
|
||||
|
||||
public AbstractEntityDiscriminatorMapping(
|
||||
EntityPersister entityDescriptor,
|
||||
String tableExpression,
|
||||
String mappedColumnExpression,
|
||||
boolean isFormula,
|
||||
DiscriminatorType<?> mappingType) {
|
||||
this.entityDescriptor = entityDescriptor;
|
||||
this.tableExpression = tableExpression;
|
||||
this.mappedColumnExpression = mappedColumnExpression;
|
||||
this.isFormula = isFormula;
|
||||
this.mappingType = mappingType;
|
||||
}
|
||||
|
||||
public EntityPersister getEntityDescriptor() {
|
||||
return entityDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainingTableExpression() {
|
||||
return tableExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectionExpression() {
|
||||
return mappedColumnExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormula() {
|
||||
return isFormula;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConcreteEntityNameForDiscriminatorValue(Object value) {
|
||||
return ( (Loadable) getEntityDescriptor() ).getSubclassForDiscriminatorValue( value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DomainResult<T> createDomainResult(
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
final SqlSelection sqlSelection = resolveSqlSelection( tableGroup, false, creationState );
|
||||
|
||||
//noinspection unchecked
|
||||
return new BasicResult(
|
||||
sqlSelection.getValuesArrayPosition(),
|
||||
resultVariable,
|
||||
getJavaTypeDescriptor(),
|
||||
navigablePath
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySqlSelections(
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
DomainResultCreationState creationState) {
|
||||
resolveSqlSelection( tableGroup, false, creationState );
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicFetch generateFetch(
|
||||
FetchParent fetchParent,
|
||||
NavigablePath fetchablePath,
|
||||
FetchTiming fetchTiming,
|
||||
boolean selected,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
|
||||
final TableGroup tableGroup = sqlAstCreationState.getFromClauseAccess().getTableGroup(
|
||||
fetchParent.getNavigablePath()
|
||||
);
|
||||
|
||||
assert tableGroup != null;
|
||||
|
||||
final SqlSelection sqlSelection = resolveSqlSelection( tableGroup, true, creationState );
|
||||
|
||||
return new BasicFetch<>(
|
||||
sqlSelection.getValuesArrayPosition(),
|
||||
fetchParent,
|
||||
fetchablePath,
|
||||
this,
|
||||
false,
|
||||
null,
|
||||
fetchTiming,
|
||||
creationState
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor<?> getJavaTypeDescriptor() {
|
||||
return getMappedType().getMappedJavaTypeDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiscriminatorType<?> getMappedType() {
|
||||
return mappingType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiscriminatorType<?> getPartMappingType() {
|
||||
return mappingType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcMapping getJdbcMapping() {
|
||||
return mappingType.getJdbcMapping();
|
||||
}
|
||||
|
||||
protected abstract SqlSelection resolveSqlSelection(
|
||||
TableGroup tableGroup,
|
||||
boolean underlyingType,
|
||||
DomainResultCreationState creationState);
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* 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 java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.persister.entity.DiscriminatorType;
|
||||
import org.hibernate.persister.entity.JoinedSubclassEntityPersister;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||
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.predicate.NullnessPredicate;
|
||||
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||
|
||||
import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
public class CaseStatementDiscriminatorMappingImpl extends AbstractDiscriminatorMapping {
|
||||
|
||||
private final LinkedHashMap<String,TableDiscriminatorDetails> tableDiscriminatorDetailsMap = new LinkedHashMap<>();
|
||||
|
||||
public CaseStatementDiscriminatorMappingImpl(
|
||||
JoinedSubclassEntityPersister entityDescriptor,
|
||||
String[] tableNames,
|
||||
int[] notNullColumnTableNumbers,
|
||||
String[] notNullColumnNames,
|
||||
String[] discriminatorValues,
|
||||
Map<String,String> subEntityNameByTableName,
|
||||
DiscriminatorType<?> incomingDiscriminatorType,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
super(
|
||||
incomingDiscriminatorType.getUnderlyingType().getJdbcMapping(),
|
||||
entityDescriptor,
|
||||
incomingDiscriminatorType,
|
||||
creationProcess
|
||||
);
|
||||
|
||||
for ( int i = 0; i < discriminatorValues.length; i++ ) {
|
||||
final String tableName = tableNames[notNullColumnTableNumbers[i]];
|
||||
final String subEntityName = subEntityNameByTableName.get( tableName );
|
||||
final String oneSubEntityColumn = notNullColumnNames[i];
|
||||
|
||||
final String rawDiscriminatorValue = discriminatorValues[i];
|
||||
final Object discriminatorValue = getUnderlyingJdbcMappingType().getJavaTypeDescriptor().wrap( rawDiscriminatorValue, null );
|
||||
|
||||
tableDiscriminatorDetailsMap.put(
|
||||
tableName,
|
||||
new TableDiscriminatorDetails(
|
||||
tableName,
|
||||
oneSubEntityColumn,
|
||||
discriminatorValue,
|
||||
subEntityName
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression resolveSqlExpression(
|
||||
NavigablePath navigablePath,
|
||||
JdbcMapping jdbcMappingToUse,
|
||||
TableGroup tableGroup,
|
||||
SqlAstCreationState creationState) {
|
||||
final SqlExpressionResolver expressionResolver = creationState.getSqlExpressionResolver();
|
||||
return expressionResolver.resolveSqlExpression(
|
||||
createColumnReferenceKey( tableGroup.getGroupAlias(), EntityDiscriminatorMapping.ROLE_NAME ),
|
||||
sqlAstProcessingState -> createCaseSearchedExpression( tableGroup )
|
||||
);
|
||||
}
|
||||
|
||||
private CaseSearchedExpression createCaseSearchedExpression(TableGroup entityTableGroup) {
|
||||
final CaseSearchedExpression caseSearchedExpression = new CaseSearchedExpression( this );
|
||||
|
||||
tableDiscriminatorDetailsMap.forEach( (tableName, tableDiscriminatorDetails) -> {
|
||||
TableReference tableReference;
|
||||
try {
|
||||
tableReference = entityTableGroup.resolveTableReference( entityTableGroup.getNavigablePath(), tableName );
|
||||
}
|
||||
catch (Exception e) {
|
||||
tableReference = null;
|
||||
}
|
||||
|
||||
if ( tableReference == null ) {
|
||||
// assume this is because it is a table that is not part of the processing entity's sub-hierarchy
|
||||
return;
|
||||
}
|
||||
|
||||
final Predicate predicate = new NullnessPredicate(
|
||||
new ColumnReference(
|
||||
tableReference,
|
||||
tableDiscriminatorDetails.getCheckColumnName(),
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
getJdbcMapping(),
|
||||
getSessionFactory()
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
caseSearchedExpression.when( predicate, new QueryLiteral<>(
|
||||
tableDiscriminatorDetails.getDiscriminatorValue(),
|
||||
getUnderlyingJdbcMappingType()
|
||||
) );
|
||||
} );
|
||||
|
||||
return caseSearchedExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCustomReadExpression() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCustomWriteExpression() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainingTableExpression() {
|
||||
throw new UnsupportedOperationException();
|
||||
// // this *should* only be used to create the sql-expression key, so just
|
||||
// // using the primary table expr should be fine
|
||||
// return entityDescriptor.getRootTableName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectionExpression() {
|
||||
throw new UnsupportedOperationException();
|
||||
// // this *should* only be used to create the sql-expression key, so just
|
||||
// // using the ROLE_NAME should be fine
|
||||
// return ROLE_NAME;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isFormula() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class TableDiscriminatorDetails {
|
||||
private final String tableName;
|
||||
private final String checkColumnName;
|
||||
private final Object discriminatorValue;
|
||||
private final String subclassEntityName;
|
||||
|
||||
public TableDiscriminatorDetails(String tableName, String checkColumnName, Object discriminatorValue, String subclassEntityName) {
|
||||
this.tableName = tableName;
|
||||
this.checkColumnName = checkColumnName;
|
||||
this.discriminatorValue = discriminatorValue;
|
||||
this.subclassEntityName = subclassEntityName;
|
||||
}
|
||||
|
||||
String getTableExpression() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
Object getDiscriminatorValue() {
|
||||
return discriminatorValue;
|
||||
}
|
||||
|
||||
String getSubclassEntityName() {
|
||||
return subclassEntityName;
|
||||
}
|
||||
|
||||
String getCheckColumnName() {
|
||||
return checkColumnName;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,121 +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.metamodel.mapping.internal;
|
||||
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.mapping.IndexedConsumer;
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.persister.entity.DiscriminatorType;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.type.BasicType;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EntityDiscriminatorMappingImpl extends AbstractEntityDiscriminatorMapping {
|
||||
private final NavigableRole navigableRole;
|
||||
|
||||
public EntityDiscriminatorMappingImpl(
|
||||
EntityPersister entityDescriptor,
|
||||
String tableExpression,
|
||||
String mappedColumnExpression,
|
||||
boolean isFormula,
|
||||
DiscriminatorType<?> mappingType) {
|
||||
super( entityDescriptor, tableExpression, mappedColumnExpression, isFormula, mappingType );
|
||||
this.navigableRole = entityDescriptor.getNavigableRole().append( EntityDiscriminatorMapping.ROLE_NAME );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SqlSelection resolveSqlSelection(
|
||||
TableGroup tableGroup,
|
||||
boolean underlyingType,
|
||||
DomainResultCreationState creationState) {
|
||||
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState()
|
||||
.getSqlExpressionResolver();
|
||||
|
||||
final TableReference tableReference = tableGroup.resolveTableReference(
|
||||
tableGroup.getNavigablePath()
|
||||
.append( getNavigableRole().getNavigableName() ),
|
||||
getContainingTableExpression()
|
||||
);
|
||||
final BasicType<?> type = underlyingType ? getMappedType().getUnderlyingType() : getMappedType();
|
||||
|
||||
return expressionResolver.resolveSqlSelection(
|
||||
expressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
tableReference,
|
||||
getSelectionExpression()
|
||||
),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
tableReference.getIdentificationVariable(),
|
||||
this,
|
||||
type,
|
||||
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
|
||||
)
|
||||
),
|
||||
type.getMappedJavaTypeDescriptor(),
|
||||
creationState.getSqlAstCreationState().getCreationContext().getDomainModel().getTypeConfiguration()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachDisassembledJdbcValue(
|
||||
Object value,
|
||||
Clause clause,
|
||||
int offset,
|
||||
JdbcValuesConsumer valuesConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
valuesConsumer.consume( offset, value, getJdbcMapping() );
|
||||
return getJdbcTypeCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
|
||||
action.accept( offset, getJdbcMapping() );
|
||||
return getJdbcTypeCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigableRole getNavigableRole() {
|
||||
return navigableRole;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) {
|
||||
valueConsumer.consume( domainValue, this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityMappingType findContainingEntityMapping() {
|
||||
return getEntityDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCustomReadExpression() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCustomWriteExpression() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* 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.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.persister.entity.DiscriminatorType;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||
|
||||
import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ExplicitColumnDiscriminatorMappingImpl extends AbstractDiscriminatorMapping {
|
||||
private final String tableExpression;
|
||||
private final String columnName;
|
||||
private final String columnFormula;
|
||||
|
||||
public ExplicitColumnDiscriminatorMappingImpl(
|
||||
EntityPersister entityDescriptor,
|
||||
DiscriminatorType<?> discriminatorType,
|
||||
String tableExpression,
|
||||
String columnExpression,
|
||||
boolean isFormula,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
super( discriminatorType.getJdbcMapping(), entityDescriptor, discriminatorType, creationProcess );
|
||||
this.tableExpression = tableExpression;
|
||||
if ( isFormula ) {
|
||||
columnName = null;
|
||||
columnFormula = columnExpression;
|
||||
}
|
||||
else {
|
||||
columnName = columnExpression;
|
||||
columnFormula = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression resolveSqlExpression(
|
||||
NavigablePath navigablePath,
|
||||
JdbcMapping jdbcMappingToUse,
|
||||
TableGroup tableGroup,
|
||||
SqlAstCreationState creationState) {
|
||||
final SqlExpressionResolver expressionResolver = creationState.getSqlExpressionResolver();
|
||||
|
||||
final TableReference tableReference = tableGroup.resolveTableReference( navigablePath, tableExpression );
|
||||
|
||||
return expressionResolver.resolveSqlExpression(
|
||||
createColumnReferenceKey( tableReference, EntityDiscriminatorMapping.ROLE_NAME ),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
tableReference,
|
||||
columnFormula == null ? columnName : columnFormula,
|
||||
columnFormula != null,
|
||||
null,
|
||||
null,
|
||||
jdbcMappingToUse,
|
||||
getSessionFactory()
|
||||
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainingTableExpression() {
|
||||
return tableExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectionExpression() {
|
||||
return columnName == null ? columnFormula : columnName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCustomReadExpression() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCustomWriteExpression() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormula() {
|
||||
return columnFormula != null;
|
||||
}
|
||||
}
|
|
@ -1,104 +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.metamodel.mapping.internal;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.mapping.IndexedConsumer;
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.persister.entity.DiscriminatorType;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
|
||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.type.BasicType;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
public class JoinedSubclassDiscriminatorMappingImpl extends AbstractEntityDiscriminatorMapping {
|
||||
private final NavigableRole navigableRole;
|
||||
private final CaseSearchedExpression caseSearchedExpression;
|
||||
private final CaseSearchedExpression caseSearchedExpressionUnderlying;
|
||||
|
||||
public JoinedSubclassDiscriminatorMappingImpl(
|
||||
EntityPersister entityDescriptor,
|
||||
String tableExpression,
|
||||
String mappedColumnExpression,
|
||||
boolean isFormula,
|
||||
CaseSearchedExpression caseSearchedExpression,
|
||||
List<ColumnReference> columnReferences,
|
||||
DiscriminatorType<?> mappingType) {
|
||||
super( entityDescriptor, tableExpression, mappedColumnExpression, isFormula, mappingType );
|
||||
|
||||
this.navigableRole = entityDescriptor.getNavigableRole().append( EntityDiscriminatorMapping.ROLE_NAME );
|
||||
this.caseSearchedExpression = caseSearchedExpression;
|
||||
final CaseSearchedExpression caseSearchedExpressionUnderlying = new CaseSearchedExpression( mappingType.getUnderlyingType() );
|
||||
for ( CaseSearchedExpression.WhenFragment whenFragment : caseSearchedExpression.getWhenFragments() ) {
|
||||
caseSearchedExpressionUnderlying.when( whenFragment.getPredicate(), whenFragment.getResult() );
|
||||
}
|
||||
caseSearchedExpressionUnderlying.otherwise( caseSearchedExpression.getOtherwise() );
|
||||
this.caseSearchedExpressionUnderlying = caseSearchedExpressionUnderlying;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SqlSelection resolveSqlSelection(
|
||||
TableGroup tableGroup,
|
||||
boolean underlyingType,
|
||||
DomainResultCreationState creationState) {
|
||||
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState()
|
||||
.getSqlExpressionResolver();
|
||||
final BasicType<?> type = underlyingType ? getMappedType().getUnderlyingType() : getMappedType();
|
||||
|
||||
return expressionResolver.resolveSqlSelection(
|
||||
expressionResolver.resolveSqlExpression(
|
||||
getSelectionExpression(),
|
||||
sqlAstProcessingState -> underlyingType ? caseSearchedExpressionUnderlying : caseSearchedExpression
|
||||
),
|
||||
type.getMappedJavaTypeDescriptor(),
|
||||
creationState.getSqlAstCreationState().getCreationContext().getDomainModel().getTypeConfiguration()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigableRole getNavigableRole() {
|
||||
return navigableRole;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) {
|
||||
valueConsumer.consume( domainValue, this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityMappingType findContainingEntityMapping() {
|
||||
return getEntityDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCustomReadExpression() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCustomWriteExpression() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
|
||||
action.accept( offset, getJdbcMapping() );
|
||||
return getJdbcTypeCount();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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.model.domain.internal;
|
||||
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.query.PathException;
|
||||
import org.hibernate.query.hql.spi.SemanticPathPart;
|
||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
||||
import org.hibernate.query.sqm.IllegalPathUsageException;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
import org.hibernate.query.sqm.sql.internal.DiscriminatorPathInterpretation;
|
||||
import org.hibernate.query.sqm.sql.internal.SelfInterpretingSqmPath;
|
||||
import org.hibernate.query.sqm.sql.internal.SqmPathInterpretation;
|
||||
import org.hibernate.query.sqm.tree.domain.AbstractSqmPath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
|
||||
/**
|
||||
* SqmPath specialization for an entity discriminator
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public class DiscriminatorSqmPath extends AbstractSqmPath implements SelfInterpretingSqmPath {
|
||||
private final EntityDomainType entityDomainType;
|
||||
private final EntityMappingType entityDescriptor;
|
||||
|
||||
protected DiscriminatorSqmPath(
|
||||
SqmPathSource referencedPathSource,
|
||||
SqmPath<?> lhs,
|
||||
EntityDomainType entityDomainType,
|
||||
EntityMappingType entityDescriptor,
|
||||
NodeBuilder nodeBuilder) {
|
||||
super( lhs.getNavigablePath().append( EntityDiscriminatorMapping.ROLE_NAME ), referencedPathSource, lhs, nodeBuilder );
|
||||
this.entityDomainType = entityDomainType;
|
||||
this.entityDescriptor = entityDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
if ( ! entityDescriptor.hasSubclasses() ) {
|
||||
return walker.visitEntityTypeLiteralExpression( new SqmLiteralEntityType( entityDomainType, nodeBuilder() ) );
|
||||
}
|
||||
|
||||
return walker.visitSelfInterpretingSqmPath( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPathInterpretation<?> interpret(
|
||||
SqlAstCreationState sqlAstCreationState,
|
||||
SemanticQueryWalker sqmWalker,
|
||||
boolean jpaQueryComplianceEnabled) {
|
||||
assert entityDescriptor.hasSubclasses();
|
||||
|
||||
final TableGroup tableGroup = sqlAstCreationState.getFromClauseAccess().getTableGroup( getLhs().getNavigablePath() );
|
||||
final EntityMappingType entityMapping = ( (EntityValuedModelPart) tableGroup.getModelPart() ).getEntityMappingType();
|
||||
|
||||
return new DiscriminatorPathInterpretation( getNavigablePath(), entityMapping, tableGroup, sqlAstCreationState );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
// todo (6.0) : no idea
|
||||
}
|
||||
|
||||
@Override
|
||||
public SemanticPathPart resolvePathPart(String name, boolean isTerminal, SqmCreationState creationState) {
|
||||
throw new IllegalPathUsageException( "Discriminator cannot be de-referenced" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmTreatedPath treatAs(Class treatJavaType) throws PathException {
|
||||
throw new UnsupportedOperationException( "Cannot apply TREAT operator to discriminator path" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmTreatedPath treatAs(EntityDomainType treatTarget) throws PathException {
|
||||
throw new UnsupportedOperationException( "Cannot apply TREAT operator to discriminator path" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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.model.domain.internal;
|
||||
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.query.sqm.IllegalPathUsageException;
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
|
||||
/**
|
||||
* SqmPathSource implementation for entity discriminator
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D> {
|
||||
private final EntityDomainType<?> entityDomainType;
|
||||
private final EntityMappingType entityMapping;
|
||||
|
||||
public DiscriminatorSqmPathSource(
|
||||
DomainType<D> discriminatorValueType,
|
||||
EntityDomainType<?> entityDomainType,
|
||||
EntityMappingType entityMapping) {
|
||||
super( EntityDiscriminatorMapping.ROLE_NAME, discriminatorValueType, BindableType.SINGULAR_ATTRIBUTE );
|
||||
this.entityDomainType = entityDomainType;
|
||||
this.entityMapping = entityMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPath<D> createSqmPath(SqmPath<?> lhs) {
|
||||
return new DiscriminatorSqmPath( this, lhs, entityDomainType, entityMapping, lhs.nodeBuilder() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPathSource<?> findSubPathSource(String name) throws IllegalPathUsageException {
|
||||
throw new IllegalPathUsageException( "Entity discriminator cannot be de-referenced" );
|
||||
}
|
||||
}
|
|
@ -22,10 +22,7 @@ import org.hibernate.metamodel.model.domain.PersistentAttribute;
|
|||
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
|
||||
import org.hibernate.persister.entity.DiscriminatorMetadata;
|
||||
import org.hibernate.persister.entity.Queryable;
|
||||
import org.hibernate.query.sqm.IllegalPathUsageException;
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedEntityTypePath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
@ -71,59 +68,12 @@ public class EntityTypeImpl<J>
|
|||
else {
|
||||
discriminatorType = StandardBasicTypes.STRING;
|
||||
}
|
||||
final boolean hasSubclasses = persistentClass.hasSubclasses();
|
||||
this.discriminatorPathSource = new SqmPathSource() {
|
||||
@Override
|
||||
public String getPathName() {
|
||||
return EntityDiscriminatorMapping.ROLE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainType<?> getSqmPathType() {
|
||||
// the BasicType for Class?
|
||||
return discriminatorType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPathSource<?> findSubPathSource(String name) {
|
||||
throw new IllegalPathUsageException( "Entity discriminator cannot be de-referenced" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPath<?> createSqmPath(SqmPath lhs) {
|
||||
if ( hasSubclasses ) {
|
||||
return new SqmBasicValuedSimplePath<>(
|
||||
lhs.getNavigablePath().append( EntityDiscriminatorMapping.ROLE_NAME ),
|
||||
this,
|
||||
lhs,
|
||||
lhs.nodeBuilder()
|
||||
);
|
||||
}
|
||||
else {
|
||||
return new SqmBasicValuedEntityTypePath<>(
|
||||
lhs.getNavigablePath().append( EntityDiscriminatorMapping.ROLE_NAME ),
|
||||
EntityTypeImpl.this,
|
||||
lhs,
|
||||
lhs.nodeBuilder()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BindableType getBindableType() {
|
||||
return BindableType.SINGULAR_ATTRIBUTE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getBindableJavaType() {
|
||||
return getExpressableJavaTypeDescriptor().getJavaTypeClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor<?> getExpressableJavaTypeDescriptor() {
|
||||
return discriminatorType.getExpressableJavaTypeDescriptor();
|
||||
}
|
||||
};
|
||||
this.discriminatorPathSource = new DiscriminatorSqmPathSource<>(
|
||||
discriminatorType,
|
||||
this,
|
||||
entityPersister
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -107,7 +107,6 @@ import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
|
|||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.FilterHelper;
|
||||
import org.hibernate.internal.util.MutableBoolean;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
|
@ -167,9 +166,9 @@ import org.hibernate.metamodel.mapping.internal.BasicEntityIdentifierMappingImpl
|
|||
import org.hibernate.metamodel.mapping.internal.CompoundNaturalIdMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.EntityDiscriminatorMappingImpl;
|
||||
import org.hibernate.metamodel.mapping.internal.EntityRowIdMappingImpl;
|
||||
import org.hibernate.metamodel.mapping.internal.EntityVersionMappingImpl;
|
||||
import org.hibernate.metamodel.mapping.internal.ExplicitColumnDiscriminatorMappingImpl;
|
||||
import org.hibernate.metamodel.mapping.internal.GeneratedValuesProcessor;
|
||||
import org.hibernate.metamodel.mapping.internal.InFlightEntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper;
|
||||
|
@ -208,7 +207,6 @@ import org.hibernate.sql.Update;
|
|||
import org.hibernate.sql.ast.Clause;
|
||||
import org.hibernate.sql.ast.SqlAstJoinType;
|
||||
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
|
||||
import org.hibernate.sql.ast.spi.SqlAliasStemHelper;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
|
@ -6033,7 +6031,7 @@ public abstract class AbstractEntityPersister
|
|||
);
|
||||
}
|
||||
|
||||
discriminatorMapping = generateDiscriminatorMapping();
|
||||
discriminatorMapping = generateDiscriminatorMapping( creationProcess );
|
||||
}
|
||||
|
||||
private void postProcessAttributeMappings(MappingModelCreationProcess creationProcess, PersistentClass bootEntityDescriptor) {
|
||||
|
@ -6146,7 +6144,7 @@ public abstract class AbstractEntityPersister
|
|||
return stateArrayPosition;
|
||||
}
|
||||
|
||||
protected EntityDiscriminatorMapping generateDiscriminatorMapping() {
|
||||
protected EntityDiscriminatorMapping generateDiscriminatorMapping(MappingModelCreationProcess modelCreationProcess) {
|
||||
if ( getDiscriminatorType() == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -6158,12 +6156,13 @@ public abstract class AbstractEntityPersister
|
|||
else {
|
||||
discriminatorColumnExpression = getDiscriminatorFormulaTemplate();
|
||||
}
|
||||
return new EntityDiscriminatorMappingImpl(
|
||||
return new ExplicitColumnDiscriminatorMappingImpl (
|
||||
this,
|
||||
(DiscriminatorType<?>) getTypeDiscriminatorMetadata().getResolutionType(),
|
||||
getTableName(),
|
||||
discriminatorColumnExpression,
|
||||
getDiscriminatorFormulaTemplate() != null,
|
||||
(DiscriminatorType<?>) getTypeDiscriminatorMetadata().getResolutionType()
|
||||
modelCreationProcess
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -6591,11 +6590,6 @@ public abstract class AbstractEntityPersister
|
|||
return discriminatorMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityDiscriminatorMapping getDiscriminatorMapping(TableGroup tableGroup) {
|
||||
return discriminatorMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AttributeMapping> getAttributeMappings() {
|
||||
if ( attributeMappings == null ) {
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.hibernate.engine.spi.Mapping;
|
|||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.type.AbstractType;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.descriptor.ValueBinder;
|
||||
|
@ -50,6 +51,11 @@ public class DiscriminatorType<T> extends AbstractType implements org.hibernate.
|
|||
return underlyingType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcMapping getJdbcMapping() {
|
||||
return getUnderlyingType().getJdbcMapping();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getReturnedClass() {
|
||||
return Class.class;
|
||||
|
|
|
@ -48,7 +48,7 @@ import org.hibernate.metamodel.mapping.EntityMappingType;
|
|||
import org.hibernate.metamodel.mapping.EntityVersionMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.BasicEntityIdentifierMappingImpl;
|
||||
import org.hibernate.metamodel.mapping.internal.JoinedSubclassDiscriminatorMappingImpl;
|
||||
import org.hibernate.metamodel.mapping.internal.CaseStatementDiscriminatorMappingImpl;
|
||||
import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper;
|
||||
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
|
||||
import org.hibernate.persister.spi.PersisterCreationContext;
|
||||
|
@ -130,7 +130,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
|||
private final boolean[] isNullableSubclassTable;
|
||||
|
||||
// subclass discrimination works by assigning particular
|
||||
// values to certain combinations of null primary key
|
||||
// values to certain combinations of not-null primary key
|
||||
// values in the outer join using an SQL CASE
|
||||
private final Map<Object,String> subclassesByDiscriminatorValue = new HashMap<>();
|
||||
private final String[] discriminatorValues;
|
||||
|
@ -580,7 +580,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
|||
Subclass sc = siter.next();
|
||||
subclassClosure[k] = sc.getEntityName();
|
||||
final Table table = sc.getTable();
|
||||
subclassNameByTableName.put( table.getName(), sc.getClassName() );
|
||||
subclassNameByTableName.put( table.getName(), sc.getEntityName() );
|
||||
try {
|
||||
if ( persistentClass.isPolymorphic() ) {
|
||||
final Object discriminatorValue;
|
||||
|
@ -1218,17 +1218,6 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EntityDiscriminatorMapping generateDiscriminatorMapping() {
|
||||
EntityMappingType superMappingType = getSuperMappingType();
|
||||
if ( superMappingType != null ) {
|
||||
return superMappingType.getDiscriminatorMapping();
|
||||
}
|
||||
else {
|
||||
return super.generateDiscriminatorMapping();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EntityIdentifierMapping generateIdentifierMapping(MappingModelCreationProcess creationProcess, PersistentClass bootEntityDescriptor) {
|
||||
final Type idType = getIdentifierType();
|
||||
|
@ -1268,6 +1257,40 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
|||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EntityDiscriminatorMapping generateDiscriminatorMapping(MappingModelCreationProcess modelCreationProcess) {
|
||||
EntityMappingType superMappingType = getSuperMappingType();
|
||||
if ( superMappingType != null ) {
|
||||
return superMappingType.getDiscriminatorMapping();
|
||||
}
|
||||
|
||||
if ( hasSubclasses() ) {
|
||||
final String formula = getDiscriminatorFormulaTemplate();
|
||||
if ( explicitDiscriminatorColumnName != null || formula != null ) {
|
||||
// even though this is a joined-hierarchy the user has defined an
|
||||
// explicit discriminator column - so we can use the normal
|
||||
// discriminator mapping
|
||||
return super.generateDiscriminatorMapping( modelCreationProcess );
|
||||
}
|
||||
|
||||
org.hibernate.persister.entity.DiscriminatorType<?> discriminatorMetadataType = (org.hibernate.persister.entity.DiscriminatorType<?>) getTypeDiscriminatorMetadata().getResolutionType();
|
||||
|
||||
// otherwise, we need to use the case-statement approach
|
||||
return new CaseStatementDiscriminatorMappingImpl(
|
||||
this,
|
||||
subclassTableNameClosure,
|
||||
notNullColumnTableNumbers,
|
||||
notNullColumnNames,
|
||||
discriminatorValues,
|
||||
subclassNameByTableName,
|
||||
discriminatorMetadataType,
|
||||
modelCreationProcess
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected EntityIdentifierMapping generateNonEncapsulatedCompositeIdentifierMapping(
|
||||
MappingModelCreationProcess creationProcess,
|
||||
PersistentClass bootEntityDescriptor,
|
||||
|
@ -1310,35 +1333,6 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityDiscriminatorMapping getDiscriminatorMapping(TableGroup tableGroup) {
|
||||
if ( hasSubclasses() ) {
|
||||
if ( explicitDiscriminatorColumnName == null ) {
|
||||
final String discriminatorColumnExpression;
|
||||
if ( getDiscriminatorFormulaTemplate() == null ) {
|
||||
discriminatorColumnExpression = getDiscriminatorColumnName();
|
||||
}
|
||||
else {
|
||||
discriminatorColumnExpression = getDiscriminatorFormulaTemplate();
|
||||
}
|
||||
CaseSearchedExpressionInfo info = getCaseSearchedExpression( tableGroup );
|
||||
return new JoinedSubclassDiscriminatorMappingImpl(
|
||||
this,
|
||||
getTableName(),
|
||||
discriminatorColumnExpression,
|
||||
getDiscriminatorFormulaTemplate() != null,
|
||||
info.caseSearchedExpression,
|
||||
info.columnReferences,
|
||||
(org.hibernate.persister.entity.DiscriminatorType<?>) getTypeDiscriminatorMetadata().getResolutionType()
|
||||
);
|
||||
}
|
||||
else {
|
||||
return super.getDiscriminatorMapping( tableGroup );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitConstraintOrderedTables(ConstraintOrderedTableConsumer consumer) {
|
||||
for ( int i = 0; i < constraintOrderedTableNames.length; i++ ) {
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.hibernate.mapping.PersistentClass;
|
|||
import org.hibernate.mapping.Subclass;
|
||||
import org.hibernate.mapping.Table;
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
|
||||
import org.hibernate.persister.spi.PersisterCreationContext;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.SelectFragment;
|
||||
|
@ -405,9 +406,9 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected EntityDiscriminatorMapping generateDiscriminatorMapping() {
|
||||
protected EntityDiscriminatorMapping generateDiscriminatorMapping(MappingModelCreationProcess modelCreationProcess) {
|
||||
if ( hasSubclasses() ) {
|
||||
return super.generateDiscriminatorMapping();
|
||||
return super.generateDiscriminatorMapping( modelCreationProcess );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ package org.hibernate.query.sqm;
|
|||
import java.util.List;
|
||||
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.metamodel.model.domain.internal.DiscriminatorSqmPath;
|
||||
import org.hibernate.query.sqm.sql.internal.SelfInterpretingSqmPath;
|
||||
import org.hibernate.query.sqm.tree.cte.SqmCteContainer;
|
||||
import org.hibernate.query.sqm.tree.cte.SqmCteStatement;
|
||||
import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement;
|
||||
|
@ -144,6 +146,8 @@ public interface SemanticQueryWalker<T> {
|
|||
T visitEntityValuedPath(SqmEntityValuedSimplePath<?> path);
|
||||
|
||||
T visitPluralValuedPath(SqmPluralValuedSimplePath<?> path);
|
||||
|
||||
T visitSelfInterpretingSqmPath(SelfInterpretingSqmPath sqmPath);
|
||||
|
||||
T visitIndexedPluralAccessPath(SqmIndexedCollectionAccessPath path);
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Locale;
|
|||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.query.QueryLogging;
|
||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||
import org.hibernate.query.sqm.sql.internal.SelfInterpretingSqmPath;
|
||||
import org.hibernate.query.sqm.tree.SqmStatement;
|
||||
import org.hibernate.query.sqm.tree.cte.SqmCteContainer;
|
||||
import org.hibernate.query.sqm.tree.cte.SqmCteStatement;
|
||||
|
@ -584,6 +585,13 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitSelfInterpretingSqmPath(SelfInterpretingSqmPath sqmPath) {
|
||||
logWithIndentation( "-> [self-interpreting-path] - `%s`", sqmPath.getNavigablePath().getFullPath() );
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitEntityValuedPath(SqmEntityValuedSimplePath path) {
|
||||
logWithIndentation( "-> [entity-path] - `%s`", path.getNavigablePath().getFullPath() );
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.List;
|
|||
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||
import org.hibernate.query.sqm.sql.internal.SelfInterpretingSqmPath;
|
||||
import org.hibernate.query.sqm.tree.SqmStatement;
|
||||
import org.hibernate.query.sqm.tree.cte.SqmCteContainer;
|
||||
import org.hibernate.query.sqm.tree.cte.SqmCteStatement;
|
||||
|
@ -287,6 +288,11 @@ public abstract class BaseSemanticQueryWalker implements SemanticQueryWalker<Obj
|
|||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitSelfInterpretingSqmPath(SelfInterpretingSqmPath sqmPath) {
|
||||
return sqmPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitIndexedPluralAccessPath(SqmIndexedCollectionAccessPath path) {
|
||||
return path;
|
||||
|
|
|
@ -72,6 +72,7 @@ import org.hibernate.metamodel.model.domain.AllowableParameterType;
|
|||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
|
||||
import org.hibernate.metamodel.model.domain.internal.CompositeSqmPathSource;
|
||||
import org.hibernate.metamodel.model.domain.internal.DiscriminatorSqmPath;
|
||||
import org.hibernate.param.VersionTypeSeedParameterSpecification;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
@ -104,6 +105,7 @@ import org.hibernate.query.sqm.sql.internal.EmbeddableValuedPathInterpretation;
|
|||
import org.hibernate.query.sqm.sql.internal.EntityValuedPathInterpretation;
|
||||
import org.hibernate.query.sqm.sql.internal.NonAggregatedCompositeValuedPathInterpretation;
|
||||
import org.hibernate.query.sqm.sql.internal.PluralValuedSimplePathInterpretation;
|
||||
import org.hibernate.query.sqm.sql.internal.SelfInterpretingSqmPath;
|
||||
import org.hibernate.query.sqm.sql.internal.SqlAstProcessingStateImpl;
|
||||
import org.hibernate.query.sqm.sql.internal.SqlAstQueryPartProcessingStateImpl;
|
||||
import org.hibernate.query.sqm.sql.internal.SqmMapEntryResult;
|
||||
|
@ -2381,6 +2383,11 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
return PluralValuedSimplePathInterpretation.from( sqmPath, this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitSelfInterpretingSqmPath(SelfInterpretingSqmPath sqmPath) {
|
||||
return sqmPath.interpret( this, this, jpaQueryComplianceEnabled );
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// General expressions
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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.query.sqm.sql.internal;
|
||||
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.results.SqlSelectionImpl;
|
||||
import org.hibernate.sql.ast.SqlAstWalker;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* SqmPathInterpretation and DomainResultProducer implementation for entity discriminator
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DiscriminatorPathInterpretation extends AbstractSqmPathInterpretation implements DomainResultProducer {
|
||||
private final Expression expression;
|
||||
|
||||
public DiscriminatorPathInterpretation(
|
||||
NavigablePath navigablePath,
|
||||
EntityMappingType mapping,
|
||||
TableGroup tableGroup,
|
||||
SqlAstCreationState sqlAstCreationState) {
|
||||
super( navigablePath, mapping.getDiscriminatorMapping(), tableGroup );
|
||||
|
||||
final JdbcMapping jdbcMappingToUse = mapping.getDiscriminatorMapping().getJdbcMapping();
|
||||
expression = getDiscriminatorMapping().resolveSqlExpression( navigablePath, jdbcMappingToUse, tableGroup, sqlAstCreationState );
|
||||
}
|
||||
|
||||
public EntityDiscriminatorMapping getDiscriminatorMapping() {
|
||||
return (EntityDiscriminatorMapping) super.getExpressionType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityDiscriminatorMapping getExpressionType() {
|
||||
return getDiscriminatorMapping();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlSelection createSqlSelection(
|
||||
int jdbcPosition,
|
||||
int valuesArrayPosition,
|
||||
JavaTypeDescriptor javaTypeDescriptor,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
return new SqlSelectionImpl( valuesArrayPosition, getDiscriminatorMapping() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainResult<Class<?>> createDomainResult(String resultVariable, DomainResultCreationState creationState) {
|
||||
return getDiscriminatorMapping().createDomainResult( getNavigablePath(), getTableGroup(), resultVariable, creationState );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(SqlAstWalker sqlTreeWalker) {
|
||||
expression.accept( sqlTreeWalker );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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.query.sqm.sql.internal;
|
||||
|
||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
|
||||
/**
|
||||
* Optional contract for sqm-paths which need special interpretation handling
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface SelfInterpretingSqmPath<T> extends SqmPath<T> {
|
||||
/**
|
||||
* Perform the interpretation
|
||||
*/
|
||||
SqmPathInterpretation<T> interpret(
|
||||
SqlAstCreationState sqlAstCreationState,
|
||||
SemanticQueryWalker<?> sqmWalker,
|
||||
boolean jpaQueryComplianceEnabled);
|
||||
}
|
|
@ -39,24 +39,12 @@ public abstract class AbstractEntityResultGraphNode extends AbstractFetchParent
|
|||
private final BasicFetch<?> discriminatorFetch;
|
||||
private final DomainResult<Object> rowIdResult;
|
||||
|
||||
private final EntityMappingType targetType;
|
||||
|
||||
public AbstractEntityResultGraphNode(
|
||||
EntityValuedModelPart referencedModelPart,
|
||||
NavigablePath navigablePath,
|
||||
DomainResultCreationState creationState) {
|
||||
this( referencedModelPart, navigablePath, null, creationState );
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public AbstractEntityResultGraphNode(
|
||||
EntityValuedModelPart referencedModelPart,
|
||||
NavigablePath navigablePath,
|
||||
EntityMappingType targetType,
|
||||
DomainResultCreationState creationState) {
|
||||
super( referencedModelPart.getEntityMappingType(), navigablePath );
|
||||
this.referencedModelPart = referencedModelPart;
|
||||
this.targetType = targetType;
|
||||
|
||||
final EntityMappingType entityDescriptor = referencedModelPart.getEntityMappingType();
|
||||
|
||||
|
@ -100,9 +88,9 @@ public abstract class AbstractEntityResultGraphNode extends AbstractFetchParent
|
|||
);
|
||||
}
|
||||
|
||||
final EntityDiscriminatorMapping discriminatorMapping = getDiscriminatorMapping( entityDescriptor, entityTableGroup );
|
||||
final EntityDiscriminatorMapping discriminatorMapping = entityDescriptor.getDiscriminatorMapping();
|
||||
// No need to fetch the discriminator if this type does not have subclasses
|
||||
if ( discriminatorMapping != null && entityDescriptor.getEntityPersister().getEntityMetamodel().hasSubclasses() ) {
|
||||
if ( discriminatorMapping != null && entityDescriptor.hasSubclasses() ) {
|
||||
discriminatorFetch = discriminatorMapping.generateFetch(
|
||||
this,
|
||||
navigablePath.append( EntityDiscriminatorMapping.ROLE_NAME ),
|
||||
|
@ -168,12 +156,6 @@ public abstract class AbstractEntityResultGraphNode extends AbstractFetchParent
|
|||
}
|
||||
}
|
||||
|
||||
protected EntityDiscriminatorMapping getDiscriminatorMapping(
|
||||
EntityMappingType entityDescriptor,
|
||||
TableGroup entityTableGroup) {
|
||||
return entityDescriptor.getDiscriminatorMapping( entityTableGroup );
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityMappingType getReferencedMappingContainer() {
|
||||
return getEntityValuedModelPart().getEntityMappingType();
|
||||
|
|
|
@ -6,10 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.sql.results.graph.entity.internal;
|
||||
|
||||
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.graph.AssemblerCreationState;
|
||||
|
@ -49,16 +46,4 @@ public class EntityResultJoinedSubclassImpl extends EntityResultImpl {
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.sql.SQLException;
|
|||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
||||
import org.hibernate.type.descriptor.ValueExtractor;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
|
||||
|
@ -24,11 +25,11 @@ public class ConvertedValueExtractor<O,R> implements ValueExtractor<O> {
|
|||
private static final Logger log = Logger.getLogger( ConvertedValueExtractor.class );
|
||||
|
||||
private final ValueExtractor<R> relationalExtractor;
|
||||
private final AttributeConverter<O,R> converter;
|
||||
private final BasicValueConverter<O,R> converter;
|
||||
|
||||
public ConvertedValueExtractor(
|
||||
ValueExtractor<R> relationalExtractor,
|
||||
AttributeConverter<O, R> converter) {
|
||||
BasicValueConverter<O, R> converter) {
|
||||
this.relationalExtractor = relationalExtractor;
|
||||
this.converter = converter;
|
||||
}
|
||||
|
@ -50,7 +51,7 @@ public class ConvertedValueExtractor<O,R> implements ValueExtractor<O> {
|
|||
|
||||
private O doConversion(R extractedValue) {
|
||||
try {
|
||||
O convertedValue = converter.convertToEntityAttribute( extractedValue );
|
||||
O convertedValue = converter.toDomainValue( extractedValue );
|
||||
log.debugf( "Converted value on extraction: %s -> %s", extractedValue, convertedValue );
|
||||
return convertedValue;
|
||||
}
|
||||
|
|
|
@ -643,7 +643,12 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
|
|||
}
|
||||
|
||||
@Override
|
||||
public EntityDiscriminatorMapping getDiscriminatorMapping(TableGroup tableGroup) {
|
||||
public Object getDiscriminatorValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSubclassForDiscriminatorValue(Object value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -696,7 +696,12 @@ public class PersisterClassProviderTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public EntityDiscriminatorMapping getDiscriminatorMapping(TableGroup tableGroup) {
|
||||
public Object getDiscriminatorValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSubclassForDiscriminatorValue(Object value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -754,7 +754,12 @@ public class CustomPersister implements EntityPersister {
|
|||
}
|
||||
|
||||
@Override
|
||||
public EntityDiscriminatorMapping getDiscriminatorMapping(TableGroup tableGroup) {
|
||||
public Object getDiscriminatorValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSubclassForDiscriminatorValue(Object value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id: Address.java 4373 2004-08-18 09:18:34Z oneovthafew $
|
||||
package org.hibernate.orm.test.discriminator;
|
||||
package org.hibernate.orm.test.mapping.inheritance.discriminator;
|
||||
|
||||
|
||||
/**
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id: Customer.java 4373 2004-08-18 09:18:34Z oneovthafew $
|
||||
package org.hibernate.orm.test.discriminator;
|
||||
package org.hibernate.orm.test.mapping.inheritance.discriminator;
|
||||
|
||||
|
||||
/**
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.orm.test.discriminator;
|
||||
package org.hibernate.orm.test.mapping.inheritance.discriminator;
|
||||
|
||||
import javax.persistence.Tuple;
|
||||
|
||||
|
@ -21,7 +21,7 @@ import org.assertj.core.api.Assertions;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/orm/test/discriminator/Person.hbm.xml"
|
||||
xmlMappings = "org/hibernate/orm/test/mapping/inheritance/discriminator/Person.hbm.xml"
|
||||
)
|
||||
@SessionFactory
|
||||
public class DiscriminatorQueryUsageTests {
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* 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>.
|
||||
* 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;
|
||||
package org.hibernate.orm.test.mapping.inheritance.discriminator;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
@ -37,7 +37,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|||
* @author Gavin King
|
||||
*/
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/orm/test/discriminator/Person.hbm.xml"
|
||||
xmlMappings = "org/hibernate/orm/test/mapping/inheritance/discriminator/Person.hbm.xml"
|
||||
)
|
||||
@SessionFactory
|
||||
public class DiscriminatorTest {
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id: Employee.java 4373 2004-08-18 09:18:34Z oneovthafew $
|
||||
package org.hibernate.orm.test.discriminator;
|
||||
package org.hibernate.orm.test.mapping.inheritance.discriminator;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id: Employee.java 4373 2004-08-18 09:18:34Z oneovthafew $
|
||||
package org.hibernate.orm.test.discriminator;
|
||||
package org.hibernate.orm.test.mapping.inheritance.discriminator;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
|
@ -18,7 +18,7 @@
|
|||
-->
|
||||
|
||||
<hibernate-mapping
|
||||
package="org.hibernate.orm.test.discriminator"
|
||||
package="org.hibernate.orm.test.mapping.inheritance.discriminator"
|
||||
default-access="field">
|
||||
|
||||
<class name="Person"
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id: Person.java 4373 2004-08-18 09:18:34Z oneovthafew $
|
||||
package org.hibernate.orm.test.discriminator;
|
||||
package org.hibernate.orm.test.mapping.inheritance.discriminator;
|
||||
|
||||
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping
|
||||
package="org.hibernate.orm.test.discriminator"
|
||||
package="org.hibernate.orm.test.mapping.inheritance.discriminator"
|
||||
default-access="field">
|
||||
|
||||
<!--
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* 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>.
|
||||
* 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;
|
||||
package org.hibernate.orm.test.mapping.inheritance.discriminator;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
@ -34,7 +34,10 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|||
* @author Gavin King
|
||||
*/
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/orm/test/discriminator/SimpleInheritance.hbm.xml"
|
||||
xmlMappings = {
|
||||
"org/hibernate/orm/test/mapping/inheritance/discriminator/SimpleInheritance.hbm.xml",
|
||||
"org/hibernate/orm/test/mapping/inheritance/discriminator/Person.hbm.xml"
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
public class SimpleInheritanceTest {
|
||||
|
@ -81,28 +84,28 @@ public class SimpleInheritanceTest {
|
|||
}
|
||||
|
||||
assertThat(
|
||||
s.createQuery( "from org.hibernate.orm.test.discriminator.Person" ).list().size(),
|
||||
s.createQuery( "from Person" ).list().size(),
|
||||
is( 3 )
|
||||
);
|
||||
assertThat( s.createQuery(
|
||||
"from org.hibernate.orm.test.discriminator.Person p where p.class = org.hibernate.orm.test.discriminator.Person" )
|
||||
"from Person p where p.class = Person" )
|
||||
.list()
|
||||
.size(), is( 1 ) );
|
||||
assertThat( s.createQuery(
|
||||
"from org.hibernate.orm.test.discriminator.Person p where p.class = org.hibernate.orm.test.discriminator.Customer" )
|
||||
"from Person p where p.class = Customer" )
|
||||
.list()
|
||||
.size(), is( 1 ) );
|
||||
assertThat( s.createQuery( "from org.hibernate.orm.test.discriminator.Person p where type(p) = :who" )
|
||||
assertThat( s.createQuery( "from Person p where type(p) = :who" )
|
||||
.setParameter( "who", Person.class )
|
||||
.list()
|
||||
.size(), is( 1 ) );
|
||||
assertThat( s.createQuery( "from org.hibernate.orm.test.discriminator.Person p where type(p) in :who" )
|
||||
assertThat( s.createQuery( "from Person p where type(p) in :who" )
|
||||
.setParameterList( "who", new Class[] { Customer.class, Person.class } )
|
||||
.list()
|
||||
.size(), is( 2 ) );
|
||||
s.clear();
|
||||
|
||||
List<Customer> customers = s.createQuery( "from org.hibernate.orm.test.discriminator.Customer" ).list();
|
||||
List<Customer> customers = s.createQuery( "from Customer" ).list();
|
||||
for ( Customer c : customers ) {
|
||||
assertThat( c.getComments(), is( "Very demanding" ) );
|
||||
}
|
||||
|
@ -115,7 +118,7 @@ public class SimpleInheritanceTest {
|
|||
s.delete( mark );
|
||||
s.delete( joe );
|
||||
s.delete( yomomma );
|
||||
assertTrue( s.createQuery( "from org.hibernate.orm.test.discriminator.Person" ).list().isEmpty() );
|
||||
assertTrue( s.createQuery( "from Person" ).list().isEmpty() );
|
||||
|
||||
}
|
||||
);
|
||||
|
@ -173,13 +176,13 @@ public class SimpleInheritanceTest {
|
|||
q.setSalary( new BigDecimal( 1000 ) );
|
||||
s.save( q );
|
||||
|
||||
List result = s.createQuery( "from org.hibernate.orm.test.discriminator.Person where salary > 100" )
|
||||
List result = s.createQuery( "from Person where salary > 100" )
|
||||
.list();
|
||||
assertThat( result.size(), is( 1 ) );
|
||||
assertSame( result.get( 0 ), q );
|
||||
|
||||
result = s.createQuery(
|
||||
"from org.hibernate.orm.test.discriminator.Person where salary > 100 or name like 'E%'" )
|
||||
"from Person where salary > 100 or name like 'E%'" )
|
||||
.list();
|
||||
assertThat( result.size(), is( 2 ) );
|
||||
|
||||
|
@ -226,7 +229,7 @@ public class SimpleInheritanceTest {
|
|||
assertTrue( pLoad instanceof HibernateProxy );
|
||||
Person pGet = s.get( Person.class, employee.getId() );
|
||||
Person pQuery = (Person) s.createQuery(
|
||||
"from org.hibernate.orm.test.discriminator.Person where id = :id" )
|
||||
"from Person where id = :id" )
|
||||
.setParameter( "id", employee.getId() )
|
||||
.uniqueResult();
|
||||
|
||||
|
@ -277,7 +280,7 @@ public class SimpleInheritanceTest {
|
|||
s.evict( pLoad );
|
||||
Employee pGet = (Employee) s.get( Person.class, employee.getId() );
|
||||
Employee pQuery = (Employee) s.createQuery(
|
||||
"from org.hibernate.orm.test.discriminator.Person where id = :id" )
|
||||
"from Person where id = :id" )
|
||||
.setParameter( "id", employee.getId() )
|
||||
.uniqueResult();
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.orm.test.discriminator.joined;
|
||||
package org.hibernate.orm.test.mapping.inheritance.discriminator.joined;
|
||||
|
||||
/**
|
||||
* @author Chris Cranford
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.orm.test.discriminator.joined;
|
||||
package org.hibernate.orm.test.mapping.inheritance.discriminator.joined;
|
||||
|
||||
import javax.persistence.Tuple;
|
||||
|
||||
|
@ -21,7 +21,7 @@ import org.assertj.core.api.Assertions;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/orm/test/discriminator/joined/JoinedSubclassInheritance.hbm.xml"
|
||||
xmlMappings = "org/hibernate/orm/test/mapping/inheritance/discriminator/joined/JoinedSubclassInheritance.hbm.xml"
|
||||
)
|
||||
@SessionFactory
|
||||
public class DiscriminatorQueryUsageTests {
|
|
@ -3,18 +3,18 @@
|
|||
<!--
|
||||
~ 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>.
|
||||
~ 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
|
||||
-->
|
||||
<!DOCTYPE hibernate-mapping PUBLIC
|
||||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
"-//Hibernate/Hibernate Mapping DTD 4.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-4.0.xsd">
|
||||
|
||||
<hibernate-mapping
|
||||
package="org.hibernate.orm.test.discriminator.joined"
|
||||
package="org.hibernate.orm.test.mapping.inheritance.discriminator.joined"
|
||||
default-access="field">
|
||||
|
||||
<class name="org.hibernate.orm.test.discriminator.joined.ParentEntity" discriminator-value="pe">
|
||||
<class name="ParentEntity" discriminator-value="pe">
|
||||
<id name="id" type="integer">
|
||||
<column name="id"/>
|
||||
</id>
|
||||
|
@ -24,7 +24,7 @@
|
|||
<property name="type" insert="false" update="false" type="string"/>
|
||||
</class>
|
||||
|
||||
<joined-subclass name="org.hibernate.orm.test.discriminator.joined.ChildEntity" discriminator-value="ce" extends="org.hibernate.orm.test.discriminator.joined.ParentEntity">
|
||||
<joined-subclass name="ChildEntity" discriminator-value="ce" extends="ParentEntity">
|
||||
<key>
|
||||
<column name="id" />
|
||||
</key>
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* 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>.
|
||||
* 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;
|
||||
package org.hibernate.orm.test.mapping.inheritance.discriminator.joined;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
|
@ -21,7 +21,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
|||
*/
|
||||
@TestForIssue(jiraKey = "HHH-11133")
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/orm/test/discriminator/joined/JoinedSubclassInheritance.hbm.xml"
|
||||
xmlMappings = "org/hibernate/orm/test/mapping/inheritance/discriminator/joined/JoinedSubclassInheritance.hbm.xml"
|
||||
)
|
||||
@SessionFactory
|
||||
public class JoinedSubclassInheritanceTest {
|
||||
|
@ -37,9 +37,7 @@ public class JoinedSubclassInheritanceTest {
|
|||
@Test
|
||||
public void testConfiguredDiscriminatorValue(SessionFactoryScope scope) {
|
||||
final ChildEntity childEntity = new ChildEntity( 1, "Child" );
|
||||
scope.inTransaction( session ->
|
||||
session.save( childEntity )
|
||||
);
|
||||
scope.inTransaction( session -> session.save( childEntity ) );
|
||||
|
||||
scope.inTransaction( session -> {
|
||||
ChildEntity ce = session.find( ChildEntity.class, 1 );
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.orm.test.discriminator.joined;
|
||||
package org.hibernate.orm.test.mapping.inheritance.discriminator.joined;
|
||||
|
||||
/**
|
||||
* @author Chris Cranford
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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.mapping.inheritance.dynamic;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.tuple.DynamicMapInstantiator;
|
||||
|
||||
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 static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@DomainModel( xmlMappings = "org/hibernate/orm/test/mapping/inheritance/dynamic/JoinedMappings.hbm.xml" )
|
||||
@SessionFactory
|
||||
public class DynamicJoinedInheritanceTests {
|
||||
@Test
|
||||
public void testLoading(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
final Map<String,?> entity = (Map<String, ?>) session.get( "Sub", 1 );
|
||||
assertThat( entity ).isNotNull();
|
||||
assertThat( entity.get( DynamicMapInstantiator.KEY ) ).isNotNull();
|
||||
assertThat( entity.get( DynamicMapInstantiator.KEY ) ).isEqualTo( "Sub" );
|
||||
} );
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void createTestData(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
final HashMap<Object, Object> entity = new HashMap<>();
|
||||
entity.put( "id", 1 );
|
||||
entity.put( "name", "sub" );
|
||||
entity.put( "subText", "" );
|
||||
session.save( "Sub", entity );
|
||||
} );
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void dropTestData(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
session.createQuery( "delete Sub" ).executeUpdate();
|
||||
} );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE hibernate-mapping PUBLIC
|
||||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<!--
|
||||
|
||||
This mapping demonstrates content-based discrimination for the
|
||||
table-per-hierarchy mapping strategy, using a formula
|
||||
discriminator.
|
||||
|
||||
-->
|
||||
|
||||
<hibernate-mapping
|
||||
package="org.hibernate.orm.test.mapping.inheritance.dynamic"
|
||||
default-access="field">
|
||||
|
||||
<class abstract="true" entity-name="Base" table="t_base">
|
||||
<id type="integer" />
|
||||
<property name="name" type="string"/>
|
||||
|
||||
<joined-subclass entity-name="Sub" table="t_sub">
|
||||
<key column="sub_id"/>
|
||||
<property name="subText" type="string"/>
|
||||
</joined-subclass>
|
||||
</class>
|
||||
</hibernate-mapping>
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* 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 for testing inheritance with dynamic entity models (MAP, entity-name)
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
package org.hibernate.orm.test.mapping.inheritance.dynamic;
|
|
@ -16,6 +16,11 @@ appender.unclosedSessionFactoryFile.fileName=target/tmp/log/UnclosedSessionFacto
|
|||
appender.unclosedSessionFactoryFile.layout.type=PatternLayout
|
||||
appender.unclosedSessionFactoryFile.layout.pattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
|
||||
|
||||
appender.ddl.type=Console
|
||||
appender.ddl.name=DDL
|
||||
appender.ddl.layout.type=PatternLayout
|
||||
appender.ddl.layout.pattern=%d{ABSOLUTE} %5p %c:%L - %m%n
|
||||
|
||||
rootLogger.level=info
|
||||
rootLogger.appenderRef.stdout.ref=STDOUT
|
||||
|
||||
|
@ -30,6 +35,7 @@ logger.tooling-schema-script-graph.name=org.hibernate.orm.tooling.schema.script.
|
|||
|
||||
logger.hbm2ddl.name=org.hibernate.tool.hbm2ddl
|
||||
logger.hbm2ddl.level=trace
|
||||
|
||||
logger.testing-cache.name=org.hibernate.testing.cache
|
||||
logger.testing-cache.level=debug
|
||||
|
||||
|
|
|
@ -9,6 +9,11 @@ appender.stdout.name=STDOUT
|
|||
appender.stdout.layout.type=PatternLayout
|
||||
appender.stdout.layout.pattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
|
||||
|
||||
appender.ddl.type=Console
|
||||
appender.ddl.name=DDL
|
||||
appender.ddl.layout.type=PatternLayout
|
||||
appender.ddl.layout.pattern=%d{ABSOLUTE} %5p %c:%L - %m%n
|
||||
|
||||
rootLogger.level=info
|
||||
rootLogger.appenderRef.stdout.ref=STDOUT
|
||||
|
||||
|
@ -18,13 +23,21 @@ logger.test.level=info
|
|||
# SQL Logging - HHH-6833
|
||||
logger.sql.name=org.hibernate.SQL
|
||||
logger.sql.level=debug
|
||||
|
||||
logger.hbm2ddl.name=org.hibernate.tool.hbm2ddl
|
||||
logger.hbm2ddl.level=debug
|
||||
logger.hbm2ddl.level=trace
|
||||
logger.hbm2ddl.appenderRef.stdout.ref=DDL
|
||||
|
||||
logger.type-basic-binder.name=org.hibernate.type.descriptor.jdbc.BasicBinder
|
||||
logger.type-basic-binder.level=trace
|
||||
logger.type-basic-extractor.name=org.hibernate.type.descriptor.jdbc.BasicExtractor
|
||||
logger.type-basic-extractor.level=trace
|
||||
|
||||
logger.jdbc-bind.name=org.hibernate.orm.jdbc.bind
|
||||
logger.jdbc-bind.level=trace
|
||||
|
||||
logger.jdbc-extract.name=org.hibernate.orm.jdbc.extract
|
||||
logger.jdbc-extract.level=trace
|
||||
|
||||
logger.additional-jaxb-mapping-producer-impl.name=org.hibernate.envers.boot.internal.AdditionalJaxbMappingProducerImpl
|
||||
logger.additional-jaxb-mapping-producer-impl.level=trace
|
Loading…
Reference in New Issue