Implement support for avoiding joins when accessing FK keys
This commit is contained in:
parent
c74e5ef595
commit
df9d285f2c
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.userguide.mapping.identifier.composite;
|
package org.hibernate.userguide.mapping.identifier.composite;
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
|
||||||
import org.hibernate.dialect.H2Dialect;
|
import org.hibernate.dialect.H2Dialect;
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
@ -33,15 +34,16 @@ public class EmbeddedIdDatabaseGeneratedValueTest extends BaseEntityManagerFunct
|
||||||
@TestForIssue(jiraKey = "HHH-13096")
|
@TestForIssue(jiraKey = "HHH-13096")
|
||||||
public void test() {
|
public void test() {
|
||||||
final EventId eventId = doInJPA( this::entityManagerFactory, entityManager -> {
|
final EventId eventId = doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
// On H2 1.4.199+ CURRENT_TIMESTAMP returns a timestamp with timezone
|
||||||
//tag::identifiers-composite-generated-database-example[]
|
//tag::identifiers-composite-generated-database-example[]
|
||||||
Timestamp currentTimestamp = (Timestamp) entityManager
|
OffsetDateTime currentTimestamp = (OffsetDateTime) entityManager
|
||||||
.createNativeQuery(
|
.createNativeQuery(
|
||||||
"SELECT CURRENT_TIMESTAMP" )
|
"SELECT CURRENT_TIMESTAMP" )
|
||||||
.getSingleResult();
|
.getSingleResult();
|
||||||
|
|
||||||
EventId id = new EventId();
|
EventId id = new EventId();
|
||||||
id.setCategory( 1 );
|
id.setCategory( 1 );
|
||||||
id.setCreatedOn( currentTimestamp );
|
id.setCreatedOn( Timestamp.from( currentTimestamp.toInstant() ) );
|
||||||
|
|
||||||
Event event = new Event();
|
Event event = new Event();
|
||||||
event.setId( id );
|
event.setId( id );
|
||||||
|
|
|
@ -101,7 +101,7 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
|
||||||
final List<Fetch> fetches = new ArrayList<>( naturalIdMapping.getNaturalIdAttributes().size() );
|
final List<Fetch> fetches = new ArrayList<>( naturalIdMapping.getNaturalIdAttributes().size() );
|
||||||
fetchParent.getReferencedMappingContainer().visitFetchables(
|
fetchParent.getReferencedMappingContainer().visitFetchables(
|
||||||
fetchable -> {
|
fetchable -> {
|
||||||
final NavigablePath navigablePath = fetchParent.getNavigablePath().append( fetchable.getFetchableName() );
|
final NavigablePath navigablePath = fetchParent.resolveNavigablePath( fetchable );
|
||||||
final Fetch fetch = fetchParent.generateFetchableFetch(
|
final Fetch fetch = fetchParent.generateFetchableFetch(
|
||||||
fetchable,
|
fetchable,
|
||||||
navigablePath,
|
navigablePath,
|
||||||
|
@ -280,7 +280,7 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
|
||||||
SelectableMapping selectableMapping,
|
SelectableMapping selectableMapping,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
SessionFactoryImplementor sessionFactory) {
|
SessionFactoryImplementor sessionFactory) {
|
||||||
final TableReference tableReference = rootTableGroup.getTableReference( selectableMapping.getContainingTableExpression() );
|
final TableReference tableReference = rootTableGroup.getTableReference( rootTableGroup.getNavigablePath(), selectableMapping.getContainingTableExpression() );
|
||||||
if ( tableReference == null ) {
|
if ( tableReference == null ) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
String.format(
|
String.format(
|
||||||
|
@ -321,7 +321,7 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
|
||||||
|
|
||||||
fetchParent.getReferencedMappingContainer().visitFetchables(
|
fetchParent.getReferencedMappingContainer().visitFetchables(
|
||||||
(fetchable) -> {
|
(fetchable) -> {
|
||||||
final NavigablePath navigablePath = fetchParent.getNavigablePath().append( fetchable.getFetchableName() );
|
final NavigablePath navigablePath = fetchParent.resolveNavigablePath( fetchable );
|
||||||
final Fetch fetch = fetchParent.generateFetchableFetch(
|
final Fetch fetch = fetchParent.generateFetchableFetch(
|
||||||
fetchable,
|
fetchable,
|
||||||
navigablePath,
|
navigablePath,
|
||||||
|
|
|
@ -109,10 +109,13 @@ class DatabaseSnapshotExecutor {
|
||||||
domainResults.add(
|
domainResults.add(
|
||||||
new QueryLiteral<>( null, IntegerType.INSTANCE ).createDomainResult( null, state )
|
new QueryLiteral<>( null, IntegerType.INSTANCE ).createDomainResult( null, state )
|
||||||
);
|
);
|
||||||
|
final NavigablePath idNavigablePath = rootPath.append( entityDescriptor.getIdentifierMapping().getNavigableRole().getNavigableName() );
|
||||||
entityDescriptor.getIdentifierMapping().forEachSelectable(
|
entityDescriptor.getIdentifierMapping().forEachSelectable(
|
||||||
(columnIndex, selection) -> {
|
(columnIndex, selection) -> {
|
||||||
final TableReference tableReference = rootTableGroup.resolveTableReference( selection.getContainingTableExpression() );
|
final TableReference tableReference = rootTableGroup.resolveTableReference(
|
||||||
|
idNavigablePath,
|
||||||
|
selection.getContainingTableExpression()
|
||||||
|
);
|
||||||
|
|
||||||
final JdbcParameter jdbcParameter = new JdbcParameterImpl( selection.getJdbcMapping() );
|
final JdbcParameter jdbcParameter = new JdbcParameterImpl( selection.getJdbcMapping() );
|
||||||
jdbcParameters.add( jdbcParameter );
|
jdbcParameters.add( jdbcParameter );
|
||||||
|
|
|
@ -467,12 +467,13 @@ public class LoaderSelectBuilder {
|
||||||
Consumer<JdbcParameter> jdbcParameterConsumer,
|
Consumer<JdbcParameter> jdbcParameterConsumer,
|
||||||
LoaderSqlAstCreationState sqlAstCreationState) {
|
LoaderSqlAstCreationState sqlAstCreationState) {
|
||||||
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
|
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
|
||||||
|
final NavigablePath navigablePath = rootNavigablePath.append( modelPart.getNavigableRole().getNavigableName() );
|
||||||
|
|
||||||
if ( numberColumns == 1 ) {
|
if ( numberColumns == 1 ) {
|
||||||
modelPart.forEachSelectable(
|
modelPart.forEachSelectable(
|
||||||
(columnIndex, selection) -> {
|
(columnIndex, selection) -> {
|
||||||
final TableReference tableReference = rootTableGroup.resolveTableReference(
|
final TableReference tableReference = rootTableGroup.resolveTableReference(
|
||||||
selection.getContainingTableExpression() );
|
navigablePath, selection.getContainingTableExpression() );
|
||||||
final ColumnReference columnRef =
|
final ColumnReference columnRef =
|
||||||
(ColumnReference) sqlExpressionResolver.resolveSqlExpression(
|
(ColumnReference) sqlExpressionResolver.resolveSqlExpression(
|
||||||
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
|
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
|
||||||
|
@ -511,7 +512,7 @@ public class LoaderSelectBuilder {
|
||||||
|
|
||||||
modelPart.forEachSelectable(
|
modelPart.forEachSelectable(
|
||||||
(columnIndex, selection) -> {
|
(columnIndex, selection) -> {
|
||||||
final TableReference tableReference = rootTableGroup.resolveTableReference( selection.getContainingTableExpression() );
|
final TableReference tableReference = rootTableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() );
|
||||||
columnReferences.add(
|
columnReferences.add(
|
||||||
(ColumnReference) sqlExpressionResolver.resolveSqlExpression(
|
(ColumnReference) sqlExpressionResolver.resolveSqlExpression(
|
||||||
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
|
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
|
||||||
|
@ -629,7 +630,6 @@ public class LoaderSelectBuilder {
|
||||||
List<Fetch> fetches,
|
List<Fetch> fetches,
|
||||||
List<String> bagRoles) {
|
List<String> bagRoles) {
|
||||||
return (fetchable, isKeyFetchable) -> {
|
return (fetchable, isKeyFetchable) -> {
|
||||||
final NavigablePath parentNavigablePath = fetchParent.getNavigablePath();
|
|
||||||
final NavigablePath fetchablePath;
|
final NavigablePath fetchablePath;
|
||||||
|
|
||||||
if ( isKeyFetchable ) {
|
if ( isKeyFetchable ) {
|
||||||
|
@ -659,16 +659,16 @@ public class LoaderSelectBuilder {
|
||||||
|
|
||||||
if ( identifierMapping != null ) {
|
if ( identifierMapping != null ) {
|
||||||
fetchablePath = new EntityIdentifierNavigablePath(
|
fetchablePath = new EntityIdentifierNavigablePath(
|
||||||
parentNavigablePath,
|
fetchParent.getNavigablePath(),
|
||||||
attributeName( identifierMapping )
|
attributeName( identifierMapping )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fetchablePath = parentNavigablePath.append( fetchable.getFetchableName() );
|
fetchablePath = fetchParent.resolveNavigablePath( fetchable );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fetchablePath = parentNavigablePath.append( fetchable.getFetchableName() );
|
fetchablePath = fetchParent.resolveNavigablePath( fetchable );
|
||||||
}
|
}
|
||||||
|
|
||||||
final Fetch biDirectionalFetch = fetchable.resolveCircularFetch(
|
final Fetch biDirectionalFetch = fetchable.resolveCircularFetch(
|
||||||
|
@ -879,6 +879,7 @@ public class LoaderSelectBuilder {
|
||||||
|
|
||||||
final PluralAttributeMapping attributeMapping = (PluralAttributeMapping) loadable;
|
final PluralAttributeMapping attributeMapping = (PluralAttributeMapping) loadable;
|
||||||
final ForeignKeyDescriptor fkDescriptor = attributeMapping.getKeyDescriptor();
|
final ForeignKeyDescriptor fkDescriptor = attributeMapping.getKeyDescriptor();
|
||||||
|
final NavigablePath navigablePath = rootNavigablePath.append( attributeMapping.getAttributeName() );
|
||||||
|
|
||||||
final Expression fkExpression;
|
final Expression fkExpression;
|
||||||
|
|
||||||
|
@ -892,7 +893,7 @@ public class LoaderSelectBuilder {
|
||||||
simpleFkDescriptor.getSelectionExpression()
|
simpleFkDescriptor.getSelectionExpression()
|
||||||
),
|
),
|
||||||
sqlAstProcessingState -> new ColumnReference(
|
sqlAstProcessingState -> new ColumnReference(
|
||||||
rootTableGroup.resolveTableReference( simpleFkDescriptor.getContainingTableExpression() ),
|
rootTableGroup.resolveTableReference( navigablePath, simpleFkDescriptor.getContainingTableExpression() ),
|
||||||
simpleFkDescriptor.getSelectionExpression(),
|
simpleFkDescriptor.getSelectionExpression(),
|
||||||
false,
|
false,
|
||||||
null,
|
null,
|
||||||
|
@ -914,7 +915,7 @@ public class LoaderSelectBuilder {
|
||||||
selection.getSelectionExpression()
|
selection.getSelectionExpression()
|
||||||
),
|
),
|
||||||
sqlAstProcessingState -> new ColumnReference(
|
sqlAstProcessingState -> new ColumnReference(
|
||||||
rootTableGroup.resolveTableReference( selection.getContainingTableExpression() ),
|
rootTableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() ),
|
||||||
selection,
|
selection,
|
||||||
this.creationContext.getSessionFactory()
|
this.creationContext.getSessionFactory()
|
||||||
)
|
)
|
||||||
|
@ -961,11 +962,12 @@ public class LoaderSelectBuilder {
|
||||||
loadingSqlAst.getFromClause().visitRoots( subQuery.getFromClause()::addRoot );
|
loadingSqlAst.getFromClause().visitRoots( subQuery.getFromClause()::addRoot );
|
||||||
|
|
||||||
final SqlExpressionResolver sqlExpressionResolver = creationState.getSqlExpressionResolver();
|
final SqlExpressionResolver sqlExpressionResolver = creationState.getSqlExpressionResolver();
|
||||||
|
final NavigablePath navigablePath = ownerTableGroup.getNavigablePath().append( attributeMapping.getAttributeName() );
|
||||||
|
|
||||||
fkDescriptor.visitTargetSelectables(
|
fkDescriptor.visitTargetSelectables(
|
||||||
(valuesPosition, selection) -> {
|
(valuesPosition, selection) -> {
|
||||||
// for each column, resolve a SqlSelection and add it to the sub-query select-clause
|
// for each column, resolve a SqlSelection and add it to the sub-query select-clause
|
||||||
final TableReference tableReference = ownerTableGroup.resolveTableReference( selection.getContainingTableExpression() );
|
final TableReference tableReference = ownerTableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() );
|
||||||
final Expression expression = sqlExpressionResolver.resolveSqlExpression(
|
final Expression expression = sqlExpressionResolver.resolveSqlExpression(
|
||||||
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
|
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
|
||||||
sqlAstProcessingState -> new ColumnReference(
|
sqlAstProcessingState -> new ColumnReference(
|
||||||
|
|
|
@ -162,6 +162,7 @@ public abstract class AbstractCompositeIdentifierMapping
|
||||||
TableGroup lhs,
|
TableGroup lhs,
|
||||||
String explicitSourceAlias,
|
String explicitSourceAlias,
|
||||||
SqlAstJoinType sqlAstJoinType,
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
@ -228,12 +229,13 @@ public abstract class AbstractCompositeIdentifierMapping
|
||||||
SqlAstCreationState sqlAstCreationState) {
|
SqlAstCreationState sqlAstCreationState) {
|
||||||
final SelectableMappings selectableMappings = getEmbeddableTypeDescriptor();
|
final SelectableMappings selectableMappings = getEmbeddableTypeDescriptor();
|
||||||
final List<ColumnReference> columnReferences = CollectionHelper.arrayList( selectableMappings.getJdbcTypeCount() );
|
final List<ColumnReference> columnReferences = CollectionHelper.arrayList( selectableMappings.getJdbcTypeCount() );
|
||||||
final TableReference defaultTableReference = tableGroup.resolveTableReference( getContainingTableExpression() );
|
final NavigablePath navigablePath = tableGroup.getNavigablePath().append( getNavigableRole().getNavigableName() );
|
||||||
|
final TableReference defaultTableReference = tableGroup.resolveTableReference( navigablePath, getContainingTableExpression() );
|
||||||
getEmbeddableTypeDescriptor().forEachSelectable(
|
getEmbeddableTypeDescriptor().forEachSelectable(
|
||||||
(columnIndex, selection) -> {
|
(columnIndex, selection) -> {
|
||||||
final TableReference tableReference = selection.getContainingTableExpression().equals( defaultTableReference.getTableExpression() )
|
final TableReference tableReference = selection.getContainingTableExpression().equals( defaultTableReference.getTableExpression() )
|
||||||
? defaultTableReference
|
? defaultTableReference
|
||||||
: tableGroup.resolveTableReference( selection.getContainingTableExpression() );
|
: tableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() );
|
||||||
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver()
|
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver()
|
||||||
.resolveSqlExpression(
|
.resolveSqlExpression(
|
||||||
SqlExpressionResolver.createColumnReferenceKey(
|
SqlExpressionResolver.createColumnReferenceKey(
|
||||||
|
|
|
@ -454,6 +454,7 @@ public class EmbeddableMappingType implements ManagedMappingType, SelectableMapp
|
||||||
attributeIndex,
|
attributeIndex,
|
||||||
bootPropertyDescriptor,
|
bootPropertyDescriptor,
|
||||||
entityPersister,
|
entityPersister,
|
||||||
|
entityPersister,
|
||||||
(EntityType) subtype,
|
(EntityType) subtype,
|
||||||
getRepresentationStrategy().resolvePropertyAccess( bootPropertyDescriptor ),
|
getRepresentationStrategy().resolvePropertyAccess( bootPropertyDescriptor ),
|
||||||
compositeType.getCascadeStyle( attributeIndex ),
|
compositeType.getCascadeStyle( attributeIndex ),
|
||||||
|
|
|
@ -32,6 +32,8 @@ public interface ForeignKeyDescriptor extends VirtualModelPart {
|
||||||
|
|
||||||
ModelPart getKeyPart();
|
ModelPart getKeyPart();
|
||||||
|
|
||||||
|
ModelPart getTargetPart();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a DomainResult for the referring-side of the fk
|
* Create a DomainResult for the referring-side of the fk
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -57,7 +57,7 @@ public abstract class AbstractDomainPath implements DomainPath {
|
||||||
SqlAstCreationState creationState) {
|
SqlAstCreationState creationState) {
|
||||||
if ( referenceModelPart instanceof BasicValuedModelPart ) {
|
if ( referenceModelPart instanceof BasicValuedModelPart ) {
|
||||||
final BasicValuedModelPart selection = (BasicValuedModelPart) referenceModelPart;
|
final BasicValuedModelPart selection = (BasicValuedModelPart) referenceModelPart;
|
||||||
final TableReference tableReference = tableGroup.resolveTableReference( selection.getContainingTableExpression() );
|
final TableReference tableReference = tableGroup.resolveTableReference( getNavigablePath(), selection.getContainingTableExpression() );
|
||||||
return creationState.getSqlExpressionResolver().resolveSqlExpression(
|
return creationState.getSqlExpressionResolver().resolveSqlExpression(
|
||||||
SqlExpressionResolver.createColumnReferenceKey(
|
SqlExpressionResolver.createColumnReferenceKey(
|
||||||
selection.getContainingTableExpression(),
|
selection.getContainingTableExpression(),
|
||||||
|
@ -221,7 +221,7 @@ public abstract class AbstractDomainPath implements DomainPath {
|
||||||
String collation,
|
String collation,
|
||||||
SortOrder sortOrder,
|
SortOrder sortOrder,
|
||||||
SqlAstCreationState creationState) {
|
SqlAstCreationState creationState) {
|
||||||
final TableReference tableReference = tableGroup.resolveTableReference( selection.getContainingTableExpression() );
|
final TableReference tableReference = tableGroup.resolveTableReference( getNavigablePath(), selection.getContainingTableExpression() );
|
||||||
final Expression expression = creationState.getSqlExpressionResolver().resolveSqlExpression(
|
final Expression expression = creationState.getSqlExpressionResolver().resolveSqlExpression(
|
||||||
SqlExpressionResolver.createColumnReferenceKey(
|
SqlExpressionResolver.createColumnReferenceKey(
|
||||||
selection.getContainingTableExpression(),
|
selection.getContainingTableExpression(),
|
||||||
|
|
|
@ -190,7 +190,7 @@ public class AnyDiscriminatorPart implements BasicValuedModelPart, FetchOptions,
|
||||||
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
|
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
|
||||||
|
|
||||||
final TableGroup tableGroup = fromClauseAccess.getTableGroup( fetchablePath.getParent().getParent() );
|
final TableGroup tableGroup = fromClauseAccess.getTableGroup( fetchablePath.getParent().getParent() );
|
||||||
final TableReference tableReference = tableGroup.getTableReference( table );
|
final TableReference tableReference = tableGroup.getTableReference( fetchablePath, table );
|
||||||
final Expression columnReference = sqlExpressionResolver.resolveSqlExpression(
|
final Expression columnReference = sqlExpressionResolver.resolveSqlExpression(
|
||||||
createColumnReferenceKey( tableReference, column ),
|
createColumnReferenceKey( tableReference, column ),
|
||||||
processingState -> new ColumnReference(
|
processingState -> new ColumnReference(
|
||||||
|
|
|
@ -153,7 +153,7 @@ public class AnyKeyPart implements BasicValuedModelPart, FetchOptions {
|
||||||
.getSessionFactory();
|
.getSessionFactory();
|
||||||
|
|
||||||
final TableGroup tableGroup = fromClauseAccess.getTableGroup( fetchParent.getNavigablePath().getParent() );
|
final TableGroup tableGroup = fromClauseAccess.getTableGroup( fetchParent.getNavigablePath().getParent() );
|
||||||
final TableReference tableReference = tableGroup.getTableReference( table );
|
final TableReference tableReference = tableGroup.getTableReference( fetchablePath, table );
|
||||||
|
|
||||||
final Expression columnReference = sqlExpressionResolver.resolveSqlExpression(
|
final Expression columnReference = sqlExpressionResolver.resolveSqlExpression(
|
||||||
SqlExpressionResolver.createColumnReferenceKey( tableReference, column ),
|
SqlExpressionResolver.createColumnReferenceKey( tableReference, column ),
|
||||||
|
|
|
@ -202,7 +202,7 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
|
||||||
.getSqlExpressionResolver();
|
.getSqlExpressionResolver();
|
||||||
final TableReference rootTableReference;
|
final TableReference rootTableReference;
|
||||||
try {
|
try {
|
||||||
rootTableReference = tableGroup.resolveTableReference( rootTable );
|
rootTableReference = tableGroup.resolveTableReference( navigablePath, rootTable );
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
|
|
|
@ -217,7 +217,11 @@ public class BasicValuedSingularAttributeMapping
|
||||||
|
|
||||||
private SqlSelection resolveSqlSelection(TableGroup tableGroup, DomainResultCreationState creationState) {
|
private SqlSelection resolveSqlSelection(TableGroup tableGroup, DomainResultCreationState creationState) {
|
||||||
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState().getSqlExpressionResolver();
|
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState().getSqlExpressionResolver();
|
||||||
final TableReference tableReference = tableGroup.resolveTableReference( getContainingTableExpression() );
|
final TableReference tableReference = tableGroup.resolveTableReference(
|
||||||
|
tableGroup.getNavigablePath()
|
||||||
|
.append( getNavigableRole().getNavigableName() ),
|
||||||
|
getContainingTableExpression()
|
||||||
|
);
|
||||||
final String tableAlias = tableReference.getIdentificationVariable();
|
final String tableAlias = tableReference.getIdentificationVariable();
|
||||||
return expressionResolver.resolveSqlSelection(
|
return expressionResolver.resolveSqlSelection(
|
||||||
expressionResolver.resolveSqlExpression(
|
expressionResolver.resolveSqlExpression(
|
||||||
|
|
|
@ -228,12 +228,13 @@ public class EmbeddedAttributeMapping
|
||||||
SqmToSqlAstConverter walker,
|
SqmToSqlAstConverter walker,
|
||||||
SqlAstCreationState sqlAstCreationState) {
|
SqlAstCreationState sqlAstCreationState) {
|
||||||
final List<ColumnReference> columnReferences = CollectionHelper.arrayList( embeddableMappingType.getJdbcTypeCount() );
|
final List<ColumnReference> columnReferences = CollectionHelper.arrayList( embeddableMappingType.getJdbcTypeCount() );
|
||||||
final TableReference defaultTableReference = tableGroup.resolveTableReference( getContainingTableExpression() );
|
final NavigablePath navigablePath = tableGroup.getNavigablePath().append( getNavigableRole().getNavigableName() );
|
||||||
|
final TableReference defaultTableReference = tableGroup.resolveTableReference( navigablePath, getContainingTableExpression() );
|
||||||
getEmbeddableTypeDescriptor().forEachSelectable(
|
getEmbeddableTypeDescriptor().forEachSelectable(
|
||||||
(columnIndex, selection) -> {
|
(columnIndex, selection) -> {
|
||||||
final TableReference tableReference = selection.getContainingTableExpression().equals( defaultTableReference.getTableExpression() )
|
final TableReference tableReference = selection.getContainingTableExpression().equals( defaultTableReference.getTableExpression() )
|
||||||
? defaultTableReference
|
? defaultTableReference
|
||||||
: tableGroup.resolveTableReference( selection.getContainingTableExpression() );
|
: tableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() );
|
||||||
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(
|
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(
|
||||||
SqlExpressionResolver.createColumnReferenceKey(
|
SqlExpressionResolver.createColumnReferenceKey(
|
||||||
tableReference,
|
tableReference,
|
||||||
|
@ -273,6 +274,7 @@ public class EmbeddedAttributeMapping
|
||||||
TableGroup lhs,
|
TableGroup lhs,
|
||||||
String explicitSourceAlias,
|
String explicitSourceAlias,
|
||||||
SqlAstJoinType sqlAstJoinType,
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
|
|
@ -176,7 +176,11 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
|
||||||
sqlExpressionResolver.resolveSqlExpression(
|
sqlExpressionResolver.resolveSqlExpression(
|
||||||
SqlExpressionResolver.createColumnReferenceKey( selection.getContainingTableExpression(), selection.getSelectionExpression() ),
|
SqlExpressionResolver.createColumnReferenceKey( selection.getContainingTableExpression(), selection.getSelectionExpression() ),
|
||||||
sqlAstProcessingState -> new ColumnReference(
|
sqlAstProcessingState -> new ColumnReference(
|
||||||
tableGroup.resolveTableReference( selection.getContainingTableExpression() ),
|
tableGroup.resolveTableReference(
|
||||||
|
tableGroup.getNavigablePath()
|
||||||
|
.append( getNavigableRole().getNavigableName() ),
|
||||||
|
selection.getContainingTableExpression()
|
||||||
|
),
|
||||||
selection,
|
selection,
|
||||||
sqlAstCreationState.getCreationContext().getSessionFactory()
|
sqlAstCreationState.getCreationContext().getSessionFactory()
|
||||||
)
|
)
|
||||||
|
@ -193,6 +197,7 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
|
||||||
TableGroup lhs,
|
TableGroup lhs,
|
||||||
String explicitSourceAlias,
|
String explicitSourceAlias,
|
||||||
SqlAstJoinType sqlAstJoinType,
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
|
|
@ -245,6 +245,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor {
|
||||||
tableGroup,
|
tableGroup,
|
||||||
null,
|
null,
|
||||||
SqlAstJoinType.INNER,
|
SqlAstJoinType.INNER,
|
||||||
|
true,
|
||||||
LockMode.NONE,
|
LockMode.NONE,
|
||||||
creationState.getSqlAstCreationState()
|
creationState.getSqlAstCreationState()
|
||||||
);
|
);
|
||||||
|
@ -370,7 +371,11 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor {
|
||||||
return tableGroup.getPrimaryTableReference();
|
return tableGroup.getPrimaryTableReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
final TableReference tableReference = lhs.resolveTableReference( table );
|
final TableReference tableReference = lhs.resolveTableReference(
|
||||||
|
lhs.getNavigablePath()
|
||||||
|
.append( getNavigableRole().getNavigableName() ),
|
||||||
|
table
|
||||||
|
);
|
||||||
if ( tableReference != null ) {
|
if ( tableReference != null ) {
|
||||||
return tableReference;
|
return tableReference;
|
||||||
}
|
}
|
||||||
|
@ -407,6 +412,11 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor {
|
||||||
return keyMappingType.getEmbeddableTypeDescriptor().getEmbeddedValueMapping();
|
return keyMappingType.getEmbeddableTypeDescriptor().getEmbeddedValueMapping();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelPart getTargetPart() {
|
||||||
|
return targetMappingType.getEmbeddableTypeDescriptor().getEmbeddedValueMapping();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MappingType getPartMappingType() {
|
public MappingType getPartMappingType() {
|
||||||
return targetMappingType.getPartMappingType();
|
return targetMappingType.getPartMappingType();
|
||||||
|
@ -437,6 +447,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor {
|
||||||
tableGroup,
|
tableGroup,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
|
true,
|
||||||
LockMode.NONE,
|
LockMode.NONE,
|
||||||
creationState.getSqlAstCreationState()
|
creationState.getSqlAstCreationState()
|
||||||
);
|
);
|
||||||
|
|
|
@ -151,7 +151,7 @@ public class EntityCollectionPart
|
||||||
final FromClauseAccess fromClauseAccess = creationState.getSqlAstCreationState().getFromClauseAccess();
|
final FromClauseAccess fromClauseAccess = creationState.getSqlAstCreationState().getFromClauseAccess();
|
||||||
creationState.registerVisitedAssociationKey( getForeignKeyDescriptor().getAssociationKey() );
|
creationState.registerVisitedAssociationKey( getForeignKeyDescriptor().getAssociationKey() );
|
||||||
|
|
||||||
fromClauseAccess.resolveTableGroup(
|
TableGroup tableGroup = fromClauseAccess.resolveTableGroup(
|
||||||
fetchablePath,
|
fetchablePath,
|
||||||
np -> {
|
np -> {
|
||||||
// We need to create one. The Result will be able to find it later by path
|
// We need to create one. The Result will be able to find it later by path
|
||||||
|
@ -166,7 +166,7 @@ public class EntityCollectionPart
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return new EntityFetchJoinedImpl( fetchParent, this, lockMode, selected, fetchablePath, creationState );
|
return new EntityFetchJoinedImpl( fetchParent, this, tableGroup, lockMode, selected, fetchablePath, creationState );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -347,6 +347,7 @@ public class EntityCollectionPart
|
||||||
TableGroup lhs,
|
TableGroup lhs,
|
||||||
String explicitSourceAlias,
|
String explicitSourceAlias,
|
||||||
SqlAstJoinType sqlAstJoinType,
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
@ -356,6 +357,7 @@ public class EntityCollectionPart
|
||||||
lhs,
|
lhs,
|
||||||
explicitSourceAlias,
|
explicitSourceAlias,
|
||||||
sqlAstJoinType,
|
sqlAstJoinType,
|
||||||
|
fetched,
|
||||||
lockMode,
|
lockMode,
|
||||||
aliasBaseGenerator,
|
aliasBaseGenerator,
|
||||||
sqlExpressionResolver,
|
sqlExpressionResolver,
|
||||||
|
|
|
@ -42,7 +42,11 @@ public class EntityDiscriminatorMappingImpl extends AbstractEntityDiscriminatorM
|
||||||
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState()
|
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState()
|
||||||
.getSqlExpressionResolver();
|
.getSqlExpressionResolver();
|
||||||
|
|
||||||
final TableReference tableReference = tableGroup.resolveTableReference( getContainingTableExpression() );
|
final TableReference tableReference = tableGroup.resolveTableReference(
|
||||||
|
tableGroup.getNavigablePath()
|
||||||
|
.append( getNavigableRole().getNavigableName() ),
|
||||||
|
getContainingTableExpression()
|
||||||
|
);
|
||||||
|
|
||||||
return expressionResolver.resolveSqlSelection(
|
return expressionResolver.resolveSqlSelection(
|
||||||
expressionResolver.resolveSqlExpression(
|
expressionResolver.resolveSqlExpression(
|
||||||
|
|
|
@ -83,7 +83,7 @@ public class EntityRowIdMappingImpl implements EntityRowIdMapping, SelectableMap
|
||||||
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
|
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
|
||||||
|
|
||||||
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
|
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
|
||||||
final TableReference columnTableReference = tableGroup.resolveTableReference( tableExpression );
|
final TableReference columnTableReference = tableGroup.resolveTableReference( navigablePath, tableExpression );
|
||||||
|
|
||||||
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
|
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
|
||||||
sqlExpressionResolver.resolveSqlExpression(
|
sqlExpressionResolver.resolveSqlExpression(
|
||||||
|
|
|
@ -149,7 +149,7 @@ public class EntityVersionMappingImpl implements EntityVersionMapping, FetchOpti
|
||||||
final TableGroup tableGroup = sqlAstCreationState.getFromClauseAccess().findTableGroup( fetchParent.getNavigablePath() );
|
final TableGroup tableGroup = sqlAstCreationState.getFromClauseAccess().findTableGroup( fetchParent.getNavigablePath() );
|
||||||
|
|
||||||
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
|
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
|
||||||
final TableReference columnTableReference = tableGroup.resolveTableReference( columnTableExpression );
|
final TableReference columnTableReference = tableGroup.resolveTableReference( fetchablePath, columnTableExpression );
|
||||||
|
|
||||||
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
|
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
|
||||||
sqlExpressionResolver.resolveSqlExpression(
|
sqlExpressionResolver.resolveSqlExpression(
|
||||||
|
@ -220,7 +220,11 @@ public class EntityVersionMappingImpl implements EntityVersionMapping, FetchOpti
|
||||||
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
|
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
|
||||||
|
|
||||||
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
|
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
|
||||||
final TableReference columnTableReference = tableGroup.resolveTableReference( columnTableExpression );
|
final TableReference columnTableReference = tableGroup.resolveTableReference(
|
||||||
|
tableGroup.getNavigablePath()
|
||||||
|
.append( getNavigableRole().getNavigableName() ),
|
||||||
|
columnTableExpression
|
||||||
|
);
|
||||||
|
|
||||||
return sqlExpressionResolver.resolveSqlSelection(
|
return sqlExpressionResolver.resolveSqlSelection(
|
||||||
sqlExpressionResolver.resolveSqlExpression(
|
sqlExpressionResolver.resolveSqlExpression(
|
||||||
|
|
|
@ -233,6 +233,7 @@ public class MappingModelCreationHelper {
|
||||||
idAttributeMappings.size(),
|
idAttributeMappings.size(),
|
||||||
bootIdSubProperty,
|
bootIdSubProperty,
|
||||||
attributeMappingType,
|
attributeMappingType,
|
||||||
|
entityPersister,
|
||||||
keyManyToOnePropertyType,
|
keyManyToOnePropertyType,
|
||||||
entityPersister.getRepresentationStrategy().resolvePropertyAccess( bootIdSubProperty ),
|
entityPersister.getRepresentationStrategy().resolvePropertyAccess( bootIdSubProperty ),
|
||||||
CascadeStyles.ALL,
|
CascadeStyles.ALL,
|
||||||
|
@ -1408,6 +1409,7 @@ public class MappingModelCreationHelper {
|
||||||
int stateArrayPosition,
|
int stateArrayPosition,
|
||||||
Property bootProperty,
|
Property bootProperty,
|
||||||
ManagedMappingType declaringType,
|
ManagedMappingType declaringType,
|
||||||
|
EntityPersister declaringEntityPersister,
|
||||||
EntityType attrType,
|
EntityType attrType,
|
||||||
PropertyAccess propertyAccess,
|
PropertyAccess propertyAccess,
|
||||||
CascadeStyle cascadeStyle,
|
CascadeStyle cascadeStyle,
|
||||||
|
@ -1454,6 +1456,7 @@ public class MappingModelCreationHelper {
|
||||||
fetchStrategy,
|
fetchStrategy,
|
||||||
entityPersister,
|
entityPersister,
|
||||||
declaringType,
|
declaringType,
|
||||||
|
declaringEntityPersister,
|
||||||
propertyAccess
|
propertyAccess
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -417,6 +417,11 @@ public class PluralAttributeMappingImpl
|
||||||
return separateCollectionTable;
|
return separateCollectionTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsTableReference(String tableExpression) {
|
||||||
|
return tableExpression.equals( separateCollectionTable );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getStateArrayPosition() {
|
public int getStateArrayPosition() {
|
||||||
return stateArrayPosition;
|
return stateArrayPosition;
|
||||||
|
@ -494,6 +499,7 @@ public class PluralAttributeMappingImpl
|
||||||
lhsTableGroup,
|
lhsTableGroup,
|
||||||
null,
|
null,
|
||||||
SqlAstJoinType.LEFT,
|
SqlAstJoinType.LEFT,
|
||||||
|
true,
|
||||||
lockMode,
|
lockMode,
|
||||||
creationState.getSqlAstCreationState()
|
creationState.getSqlAstCreationState()
|
||||||
);
|
);
|
||||||
|
@ -559,6 +565,7 @@ public class PluralAttributeMappingImpl
|
||||||
TableGroup lhs,
|
TableGroup lhs,
|
||||||
String explicitSourceAlias,
|
String explicitSourceAlias,
|
||||||
SqlAstJoinType sqlAstJoinType,
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
@ -570,6 +577,7 @@ public class PluralAttributeMappingImpl
|
||||||
lhs,
|
lhs,
|
||||||
explicitSourceAlias,
|
explicitSourceAlias,
|
||||||
sqlAstJoinType,
|
sqlAstJoinType,
|
||||||
|
fetched,
|
||||||
lockMode,
|
lockMode,
|
||||||
aliasBaseGenerator,
|
aliasBaseGenerator,
|
||||||
sqlExpressionResolver,
|
sqlExpressionResolver,
|
||||||
|
@ -582,6 +590,7 @@ public class PluralAttributeMappingImpl
|
||||||
lhs,
|
lhs,
|
||||||
explicitSourceAlias,
|
explicitSourceAlias,
|
||||||
sqlAstJoinType,
|
sqlAstJoinType,
|
||||||
|
fetched,
|
||||||
lockMode,
|
lockMode,
|
||||||
aliasBaseGenerator,
|
aliasBaseGenerator,
|
||||||
sqlExpressionResolver,
|
sqlExpressionResolver,
|
||||||
|
@ -600,12 +609,14 @@ public class PluralAttributeMappingImpl
|
||||||
TableGroup lhs,
|
TableGroup lhs,
|
||||||
String explicitSourceAlias,
|
String explicitSourceAlias,
|
||||||
SqlAstJoinType sqlAstJoinType,
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
SqlAstCreationContext creationContext) {
|
SqlAstCreationContext creationContext) {
|
||||||
final TableGroup tableGroup = createOneToManyTableGroup(
|
final TableGroup tableGroup = createOneToManyTableGroup(
|
||||||
navigablePath,
|
navigablePath,
|
||||||
|
fetched,
|
||||||
lockMode,
|
lockMode,
|
||||||
aliasBaseGenerator,
|
aliasBaseGenerator,
|
||||||
sqlExpressionResolver,
|
sqlExpressionResolver,
|
||||||
|
@ -632,6 +643,7 @@ public class PluralAttributeMappingImpl
|
||||||
|
|
||||||
private TableGroup createOneToManyTableGroup(
|
private TableGroup createOneToManyTableGroup(
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
|
boolean fetched,
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
@ -658,6 +670,7 @@ public class PluralAttributeMappingImpl
|
||||||
return new StandardTableGroup(
|
return new StandardTableGroup(
|
||||||
navigablePath,
|
navigablePath,
|
||||||
this,
|
this,
|
||||||
|
fetched,
|
||||||
lockMode,
|
lockMode,
|
||||||
primaryTableReference,
|
primaryTableReference,
|
||||||
true,
|
true,
|
||||||
|
@ -680,12 +693,14 @@ public class PluralAttributeMappingImpl
|
||||||
TableGroup lhs,
|
TableGroup lhs,
|
||||||
String explicitSourceAlias,
|
String explicitSourceAlias,
|
||||||
SqlAstJoinType sqlAstJoinType,
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
SqlAstCreationContext creationContext) {
|
SqlAstCreationContext creationContext) {
|
||||||
final TableGroup tableGroup = createCollectionTableGroup(
|
final TableGroup tableGroup = createCollectionTableGroup(
|
||||||
navigablePath,
|
navigablePath,
|
||||||
|
fetched,
|
||||||
lockMode,
|
lockMode,
|
||||||
aliasBaseGenerator,
|
aliasBaseGenerator,
|
||||||
sqlExpressionResolver,
|
sqlExpressionResolver,
|
||||||
|
@ -712,6 +727,7 @@ public class PluralAttributeMappingImpl
|
||||||
|
|
||||||
private TableGroup createCollectionTableGroup(
|
private TableGroup createCollectionTableGroup(
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
|
boolean fetched,
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
@ -840,6 +856,7 @@ public class PluralAttributeMappingImpl
|
||||||
final StandardTableGroup tableGroup = new StandardTableGroup(
|
final StandardTableGroup tableGroup = new StandardTableGroup(
|
||||||
navigablePath,
|
navigablePath,
|
||||||
this,
|
this,
|
||||||
|
fetched,
|
||||||
lockMode,
|
lockMode,
|
||||||
collectionTableReference,
|
collectionTableReference,
|
||||||
true,
|
true,
|
||||||
|
@ -931,6 +948,7 @@ public class PluralAttributeMappingImpl
|
||||||
if ( getCollectionDescriptor().isOneToMany() ) {
|
if ( getCollectionDescriptor().isOneToMany() ) {
|
||||||
return createOneToManyTableGroup(
|
return createOneToManyTableGroup(
|
||||||
navigablePath,
|
navigablePath,
|
||||||
|
false,
|
||||||
lockMode,
|
lockMode,
|
||||||
creationState.getSqlAliasBaseGenerator(),
|
creationState.getSqlAliasBaseGenerator(),
|
||||||
creationState.getSqlExpressionResolver(),
|
creationState.getSqlExpressionResolver(),
|
||||||
|
@ -940,6 +958,7 @@ public class PluralAttributeMappingImpl
|
||||||
else {
|
else {
|
||||||
return createCollectionTableGroup(
|
return createCollectionTableGroup(
|
||||||
navigablePath,
|
navigablePath,
|
||||||
|
false,
|
||||||
lockMode,
|
lockMode,
|
||||||
creationState.getSqlAliasBaseGenerator(),
|
creationState.getSqlAliasBaseGenerator(),
|
||||||
creationState.getSqlExpressionResolver(),
|
creationState.getSqlExpressionResolver(),
|
||||||
|
|
|
@ -9,12 +9,10 @@ package org.hibernate.metamodel.mapping.internal;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.IntFunction;
|
import java.util.function.IntFunction;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
|
||||||
import org.hibernate.engine.FetchStyle;
|
import org.hibernate.engine.FetchStyle;
|
||||||
import org.hibernate.engine.FetchTiming;
|
import org.hibernate.engine.FetchTiming;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
|
@ -24,17 +22,13 @@ import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
|
||||||
import org.hibernate.metamodel.mapping.MappingType;
|
import org.hibernate.metamodel.mapping.MappingType;
|
||||||
import org.hibernate.metamodel.mapping.ModelPart;
|
|
||||||
import org.hibernate.metamodel.mapping.SelectableConsumer;
|
import org.hibernate.metamodel.mapping.SelectableConsumer;
|
||||||
import org.hibernate.metamodel.mapping.SelectableMapping;
|
import org.hibernate.metamodel.mapping.SelectableMapping;
|
||||||
import org.hibernate.metamodel.mapping.SelectableMappings;
|
|
||||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
import org.hibernate.query.ComparisonOperator;
|
import org.hibernate.query.ComparisonOperator;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstJoinType;
|
import org.hibernate.sql.ast.SqlAstJoinType;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
|
@ -94,14 +88,6 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
|
||||||
return targetSide.getContainingTableExpression();
|
return targetSide.getContainingTableExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BasicValuedModelPart getKeySide() {
|
|
||||||
return keySide;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BasicValuedModelPart getTargetSide() {
|
|
||||||
return targetSide;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ForeignKeyDescriptor withKeySelectionMapping(
|
public ForeignKeyDescriptor withKeySelectionMapping(
|
||||||
IntFunction<SelectableMapping> selectableMappingAccess,
|
IntFunction<SelectableMapping> selectableMappingAccess,
|
||||||
|
@ -146,11 +132,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
|
||||||
NavigablePath collectionPath,
|
NavigablePath collectionPath,
|
||||||
TableGroup tableGroup,
|
TableGroup tableGroup,
|
||||||
DomainResultCreationState creationState) {
|
DomainResultCreationState creationState) {
|
||||||
if ( targetSide.getContainingTableExpression()
|
return createDomainResult( collectionPath, tableGroup, targetSide, creationState );
|
||||||
.equals( keySide.getContainingTableExpression() ) ) {
|
|
||||||
return createDomainResult( collectionPath, tableGroup, targetSide, creationState );
|
|
||||||
}
|
|
||||||
return createDomainResult( collectionPath, tableGroup, creationState );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -204,7 +186,10 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
|
||||||
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
|
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
|
||||||
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
|
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
|
||||||
|
|
||||||
final TableReference tableReference = tableGroup.resolveTableReference( selectableMapping.getContainingTableExpression() );
|
final TableReference tableReference = tableGroup.resolveTableReference(
|
||||||
|
navigablePath.append( getNavigableRole().getNavigableName() ),
|
||||||
|
selectableMapping.getContainingTableExpression()
|
||||||
|
);
|
||||||
final String identificationVariable = tableReference.getIdentificationVariable();
|
final String identificationVariable = tableReference.getIdentificationVariable();
|
||||||
|
|
||||||
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
|
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
|
||||||
|
@ -333,7 +318,11 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
|
||||||
return tableGroup.getPrimaryTableReference();
|
return tableGroup.getPrimaryTableReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
final TableReference tableReference = lhs.resolveTableReference( table );
|
final TableReference tableReference = lhs.resolveTableReference(
|
||||||
|
lhs.getNavigablePath()
|
||||||
|
.append( getNavigableRole().getNavigableName() ),
|
||||||
|
table
|
||||||
|
);
|
||||||
if ( tableReference != null ) {
|
if ( tableReference != null ) {
|
||||||
return tableReference;
|
return tableReference;
|
||||||
}
|
}
|
||||||
|
@ -342,10 +331,15 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModelPart getKeyPart() {
|
public BasicValuedModelPart getKeyPart() {
|
||||||
return keySide;
|
return keySide;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BasicValuedModelPart getTargetPart() {
|
||||||
|
return targetSide;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MappingType getPartMappingType() {
|
public MappingType getPartMappingType() {
|
||||||
return targetSide.getMappedType();
|
return targetSide.getMappedType();
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.mapping.internal;
|
package org.hibernate.metamodel.mapping.internal;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.engine.FetchStrategy;
|
import org.hibernate.engine.FetchStrategy;
|
||||||
import org.hibernate.engine.FetchTiming;
|
import org.hibernate.engine.FetchTiming;
|
||||||
|
@ -16,14 +20,13 @@ import org.hibernate.mapping.ManyToOne;
|
||||||
import org.hibernate.mapping.OneToOne;
|
import org.hibernate.mapping.OneToOne;
|
||||||
import org.hibernate.mapping.ToOne;
|
import org.hibernate.mapping.ToOne;
|
||||||
import org.hibernate.metamodel.mapping.AssociationKey;
|
import org.hibernate.metamodel.mapping.AssociationKey;
|
||||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||||
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
|
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
|
||||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||||
import org.hibernate.metamodel.mapping.MappingType;
|
|
||||||
import org.hibernate.metamodel.mapping.ModelPart;
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.SelectableConsumer;
|
import org.hibernate.metamodel.mapping.SelectableConsumer;
|
||||||
|
@ -42,15 +45,16 @@ import org.hibernate.sql.ast.spi.SqlAliasStemHelper;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||||
|
import org.hibernate.sql.ast.tree.from.LazyTableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.StandardTableGroup;
|
import org.hibernate.sql.ast.tree.from.StandardTableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
|
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
||||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
import org.hibernate.sql.results.graph.FetchOptions;
|
|
||||||
import org.hibernate.sql.results.graph.FetchParent;
|
import org.hibernate.sql.results.graph.FetchParent;
|
||||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
|
import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
|
||||||
import org.hibernate.sql.results.graph.entity.EntityFetch;
|
import org.hibernate.sql.results.graph.entity.EntityFetch;
|
||||||
|
@ -63,6 +67,9 @@ import org.hibernate.sql.results.graph.entity.internal.EntityResultImpl;
|
||||||
import org.hibernate.sql.results.graph.entity.internal.EntityResultJoinedSubclassImpl;
|
import org.hibernate.sql.results.graph.entity.internal.EntityResultJoinedSubclassImpl;
|
||||||
import org.hibernate.sql.results.internal.domain.CircularBiDirectionalFetchImpl;
|
import org.hibernate.sql.results.internal.domain.CircularBiDirectionalFetchImpl;
|
||||||
import org.hibernate.sql.results.internal.domain.CircularFetchImpl;
|
import org.hibernate.sql.results.internal.domain.CircularFetchImpl;
|
||||||
|
import org.hibernate.tuple.IdentifierProperty;
|
||||||
|
import org.hibernate.type.ComponentType;
|
||||||
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -85,9 +92,12 @@ public class ToOneAttributeMapping
|
||||||
private final EntityMappingType entityMappingType;
|
private final EntityMappingType entityMappingType;
|
||||||
|
|
||||||
private final String referencedPropertyName;
|
private final String referencedPropertyName;
|
||||||
|
private final String targetKeyPropertyName;
|
||||||
|
private final Set<String> targetKeyPropertyNames;
|
||||||
|
|
||||||
private final Cardinality cardinality;
|
private final Cardinality cardinality;
|
||||||
private final String bidirectionalAttributeName;
|
private final String bidirectionalAttributeName;
|
||||||
|
private final TableGroupProducer declaringTableGroupProducer;
|
||||||
|
|
||||||
private ForeignKeyDescriptor foreignKeyDescriptor;
|
private ForeignKeyDescriptor foreignKeyDescriptor;
|
||||||
private String identifyingColumnsTableExpression;
|
private String identifyingColumnsTableExpression;
|
||||||
|
@ -102,6 +112,7 @@ public class ToOneAttributeMapping
|
||||||
FetchStrategy mappedFetchStrategy,
|
FetchStrategy mappedFetchStrategy,
|
||||||
EntityMappingType entityMappingType,
|
EntityMappingType entityMappingType,
|
||||||
ManagedMappingType declaringType,
|
ManagedMappingType declaringType,
|
||||||
|
EntityPersister declaringEntityPersister,
|
||||||
PropertyAccess propertyAccess) {
|
PropertyAccess propertyAccess) {
|
||||||
super(
|
super(
|
||||||
name,
|
name,
|
||||||
|
@ -192,6 +203,35 @@ public class ToOneAttributeMapping
|
||||||
}
|
}
|
||||||
|
|
||||||
this.navigableRole = navigableRole;
|
this.navigableRole = navigableRole;
|
||||||
|
final CollectionPart.Nature nature = CollectionPart.Nature.fromName(
|
||||||
|
getNavigableRole().getParent().getLocalName()
|
||||||
|
);
|
||||||
|
if ( nature == null ) {
|
||||||
|
// This is a simple to-one association
|
||||||
|
this.declaringTableGroupProducer = declaringEntityPersister;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// This is a collection part i.e. to-many association
|
||||||
|
final String collectionRoleName = getNavigableRole().getParent().getParent().getLocalName();
|
||||||
|
this.declaringTableGroupProducer = ( (PluralAttributeMapping) declaringEntityPersister.findAttributeMapping(
|
||||||
|
collectionRoleName.substring( collectionRoleName.lastIndexOf( '.' ) + 1 )
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
if ( referencedPropertyName == null ) {
|
||||||
|
final IdentifierProperty identifierProperty = getEntityMappingType()
|
||||||
|
.getEntityPersister()
|
||||||
|
.getEntityMetamodel()
|
||||||
|
.getIdentifierProperty();
|
||||||
|
this.targetKeyPropertyName = identifierProperty.getName();
|
||||||
|
final Set<String> targetKeyPropertyNames = new HashSet<>( 2 );
|
||||||
|
targetKeyPropertyNames.add( EntityIdentifierMapping.ROLE_LOCAL_NAME );
|
||||||
|
addPrefixedPropertyNames( targetKeyPropertyNames, targetKeyPropertyName, identifierProperty.getType() );
|
||||||
|
this.targetKeyPropertyNames = targetKeyPropertyNames;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.targetKeyPropertyName = referencedPropertyName;
|
||||||
|
this.targetKeyPropertyNames = Collections.singleton( targetKeyPropertyName );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ToOneAttributeMapping(ToOneAttributeMapping original) {
|
private ToOneAttributeMapping(ToOneAttributeMapping original) {
|
||||||
|
@ -209,8 +249,33 @@ public class ToOneAttributeMapping
|
||||||
this.unwrapProxy = original.unwrapProxy;
|
this.unwrapProxy = original.unwrapProxy;
|
||||||
this.entityMappingType = original.entityMappingType;
|
this.entityMappingType = original.entityMappingType;
|
||||||
this.referencedPropertyName = original.referencedPropertyName;
|
this.referencedPropertyName = original.referencedPropertyName;
|
||||||
|
this.targetKeyPropertyName = original.targetKeyPropertyName;
|
||||||
|
this.targetKeyPropertyNames = original.targetKeyPropertyNames;
|
||||||
this.cardinality = original.cardinality;
|
this.cardinality = original.cardinality;
|
||||||
this.bidirectionalAttributeName = original.bidirectionalAttributeName;
|
this.bidirectionalAttributeName = original.bidirectionalAttributeName;
|
||||||
|
this.declaringTableGroupProducer = original.declaringTableGroupProducer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addPrefixedPropertyNames(
|
||||||
|
Set<String> targetKeyPropertyNames,
|
||||||
|
String prefix,
|
||||||
|
Type type) {
|
||||||
|
if ( type.isComponentType() ) {
|
||||||
|
targetKeyPropertyNames.add( prefix );
|
||||||
|
final ComponentType componentType = (ComponentType) type;
|
||||||
|
final String[] propertyNames = componentType.getPropertyNames();
|
||||||
|
final Type[] componentTypeSubtypes = componentType.getSubtypes();
|
||||||
|
for ( int i = 0, propertyNamesLength = propertyNames.length; i < propertyNamesLength; i++ ) {
|
||||||
|
addPrefixedPropertyNames(
|
||||||
|
targetKeyPropertyNames,
|
||||||
|
prefix + "." + propertyNames[i],
|
||||||
|
componentTypeSubtypes[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
targetKeyPropertyNames.add( prefix );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ToOneAttributeMapping copy() {
|
public ToOneAttributeMapping copy() {
|
||||||
|
@ -233,10 +298,18 @@ public class ToOneAttributeMapping
|
||||||
return this.foreignKeyDescriptor;
|
return this.foreignKeyDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean canJoinForeignKey(EntityIdentifierMapping identifierMapping) {
|
||||||
|
return isKeyReferringSide && identifierMapping == getForeignKeyDescriptor().getTargetPart();
|
||||||
|
}
|
||||||
|
|
||||||
public String getReferencedPropertyName() {
|
public String getReferencedPropertyName() {
|
||||||
return referencedPropertyName;
|
return referencedPropertyName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTargetKeyPropertyName() {
|
||||||
|
return targetKeyPropertyName;
|
||||||
|
}
|
||||||
|
|
||||||
public Cardinality getCardinality() {
|
public Cardinality getCardinality() {
|
||||||
return cardinality;
|
return cardinality;
|
||||||
}
|
}
|
||||||
|
@ -256,6 +329,21 @@ public class ToOneAttributeMapping
|
||||||
return navigableRole;
|
return navigableRole;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelPart findSubPart(String name) {
|
||||||
|
return findSubPart( name, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelPart findSubPart(String name, EntityMappingType targetType) {
|
||||||
|
// Prefer resolving the key part of the foreign key rather than the target part if possible
|
||||||
|
// This way, we don't have to register table groups the target entity type
|
||||||
|
if ( name.equals( targetKeyPropertyName ) ) {
|
||||||
|
return foreignKeyDescriptor.getKeyPart();
|
||||||
|
}
|
||||||
|
return EntityValuedFetchable.super.findSubPart( name, targetType );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Fetch resolveCircularFetch(
|
public Fetch resolveCircularFetch(
|
||||||
NavigablePath fetchablePath,
|
NavigablePath fetchablePath,
|
||||||
|
@ -476,21 +564,23 @@ public class ToOneAttributeMapping
|
||||||
assert parentNavigablePath.equals( fetchParent.getNavigablePath() );
|
assert parentNavigablePath.equals( fetchParent.getNavigablePath() );
|
||||||
|
|
||||||
if ( fetchTiming == FetchTiming.IMMEDIATE && selected ) {
|
if ( fetchTiming == FetchTiming.IMMEDIATE && selected ) {
|
||||||
|
final TableGroup tableGroup;
|
||||||
if ( fetchParent instanceof EntityResultJoinedSubclassImpl &&
|
if ( fetchParent instanceof EntityResultJoinedSubclassImpl &&
|
||||||
( (EntityPersister) fetchParent.getReferencedModePart() ).findDeclaredAttributeMapping( getPartName() ) == null ) {
|
( (EntityPersister) fetchParent.getReferencedModePart() ).findDeclaredAttributeMapping( getPartName() ) == null ) {
|
||||||
final TableGroup tableGroupJoin = createTableGroupJoin(
|
tableGroup = createTableGroupJoin(
|
||||||
fetchablePath,
|
fetchablePath,
|
||||||
|
true,
|
||||||
lockMode,
|
lockMode,
|
||||||
creationState,
|
creationState,
|
||||||
parentTableGroup
|
parentTableGroup
|
||||||
);
|
);
|
||||||
fromClauseAccess.registerTableGroup( fetchablePath, tableGroupJoin );
|
fromClauseAccess.registerTableGroup( fetchablePath, tableGroup );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fromClauseAccess.resolveTableGroup(
|
tableGroup = fromClauseAccess.resolveTableGroup(
|
||||||
fetchablePath,
|
fetchablePath,
|
||||||
np ->
|
np ->
|
||||||
createTableGroupJoin( fetchablePath, lockMode, creationState, parentTableGroup )
|
createTableGroupJoin( fetchablePath, true, lockMode, creationState, parentTableGroup )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,6 +588,7 @@ public class ToOneAttributeMapping
|
||||||
return new EntityFetchJoinedImpl(
|
return new EntityFetchJoinedImpl(
|
||||||
fetchParent,
|
fetchParent,
|
||||||
this,
|
this,
|
||||||
|
tableGroup,
|
||||||
lockMode,
|
lockMode,
|
||||||
true,
|
true,
|
||||||
fetchablePath,
|
fetchablePath,
|
||||||
|
@ -578,6 +669,7 @@ public class ToOneAttributeMapping
|
||||||
tableGroup,
|
tableGroup,
|
||||||
null,
|
null,
|
||||||
tableGroup.isInnerJoinPossible() ? SqlAstJoinType.INNER : SqlAstJoinType.LEFT,
|
tableGroup.isInnerJoinPossible() ? SqlAstJoinType.INNER : SqlAstJoinType.LEFT,
|
||||||
|
true,
|
||||||
null,
|
null,
|
||||||
creationState.getSqlAstCreationState()
|
creationState.getSqlAstCreationState()
|
||||||
);
|
);
|
||||||
|
@ -600,7 +692,7 @@ public class ToOneAttributeMapping
|
||||||
return new EntityResultImpl(
|
return new EntityResultImpl(
|
||||||
navigablePath,
|
navigablePath,
|
||||||
this,
|
this,
|
||||||
null,
|
tableGroup, null,
|
||||||
creationState
|
creationState
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -608,6 +700,7 @@ public class ToOneAttributeMapping
|
||||||
|
|
||||||
private TableGroup createTableGroupJoin(
|
private TableGroup createTableGroupJoin(
|
||||||
NavigablePath fetchablePath,
|
NavigablePath fetchablePath,
|
||||||
|
boolean fetched,
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
DomainResultCreationState creationState,
|
DomainResultCreationState creationState,
|
||||||
TableGroup parentTableGroup) {
|
TableGroup parentTableGroup) {
|
||||||
|
@ -628,6 +721,7 @@ public class ToOneAttributeMapping
|
||||||
parentTableGroup,
|
parentTableGroup,
|
||||||
null,
|
null,
|
||||||
sqlAstJoinType,
|
sqlAstJoinType,
|
||||||
|
fetched,
|
||||||
lockMode,
|
lockMode,
|
||||||
creationState.getSqlAstCreationState()
|
creationState.getSqlAstCreationState()
|
||||||
);
|
);
|
||||||
|
@ -646,22 +740,101 @@ public class ToOneAttributeMapping
|
||||||
TableGroup lhs,
|
TableGroup lhs,
|
||||||
String explicitSourceAlias,
|
String explicitSourceAlias,
|
||||||
SqlAstJoinType sqlAstJoinType,
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
SqlAstCreationContext creationContext) {
|
SqlAstCreationContext creationContext) {
|
||||||
final String aliasRoot = explicitSourceAlias == null ? sqlAliasStem : explicitSourceAlias;
|
final String aliasRoot = explicitSourceAlias == null ? sqlAliasStem : explicitSourceAlias;
|
||||||
final SqlAliasBase sqlAliasBase = aliasBaseGenerator.createSqlAliasBase( aliasRoot );
|
final SqlAliasBase sqlAliasBase = aliasBaseGenerator.createSqlAliasBase( aliasRoot );
|
||||||
|
// We can only use the parent table group if the FK is located there
|
||||||
|
// If this is false, the FK is on a join table
|
||||||
|
final boolean canUseParentTableGroup = isKeyReferringSide && declaringTableGroupProducer.containsTableReference(
|
||||||
|
identifyingColumnsTableExpression );
|
||||||
|
final LazyTableGroup lazyTableGroup = new LazyTableGroup(
|
||||||
|
navigablePath,
|
||||||
|
() -> createTableGroupJoinInternal(
|
||||||
|
navigablePath,
|
||||||
|
fetched,
|
||||||
|
null,
|
||||||
|
sqlAliasBase,
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext
|
||||||
|
),
|
||||||
|
np -> {
|
||||||
|
if ( !canUseParentTableGroup ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
NavigablePath path = np.getParent();
|
||||||
|
// Fast path
|
||||||
|
if ( path != null && navigablePath.equals( path ) ) {
|
||||||
|
return targetKeyPropertyNames.contains( np.getUnaliasedLocalName() );
|
||||||
|
}
|
||||||
|
final StringBuilder sb = new StringBuilder( np.getFullPath().length() );
|
||||||
|
sb.append( np.getUnaliasedLocalName() );
|
||||||
|
while ( path != null && !navigablePath.equals( path ) ) {
|
||||||
|
sb.insert( 0, '.' );
|
||||||
|
sb.insert( 0, path.getUnaliasedLocalName() );
|
||||||
|
path = path.getParent();
|
||||||
|
}
|
||||||
|
return path != null && navigablePath.equals( path ) && targetKeyPropertyNames.contains(
|
||||||
|
sb.toString()
|
||||||
|
);
|
||||||
|
},
|
||||||
|
this,
|
||||||
|
null,
|
||||||
|
sqlAliasBase,
|
||||||
|
creationContext.getSessionFactory(),
|
||||||
|
lhs
|
||||||
|
);
|
||||||
|
|
||||||
|
final TableReference lhsTableReference = lhs.resolveTableReference( navigablePath, identifyingColumnsTableExpression );
|
||||||
|
|
||||||
|
final TableGroupJoin tableGroupJoin = new TableGroupJoin(
|
||||||
|
navigablePath,
|
||||||
|
sqlAstJoinType,
|
||||||
|
lazyTableGroup,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
lazyTableGroup.setTableGroupInitializerCallback(
|
||||||
|
tableGroup -> tableGroupJoin.applyPredicate(
|
||||||
|
foreignKeyDescriptor.generateJoinPredicate(
|
||||||
|
lhsTableReference,
|
||||||
|
tableGroup.getPrimaryTableReference(),
|
||||||
|
sqlAstJoinType,
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
lhs.addTableGroupJoin( tableGroupJoin );
|
||||||
|
|
||||||
|
if ( sqlAstJoinType == SqlAstJoinType.INNER && isNullable ) {
|
||||||
|
// Force initialization of the underlying table group join to retain cardinality
|
||||||
|
lazyTableGroup.getPrimaryTableReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tableGroupJoin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TableGroup createTableGroupJoinInternal(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
boolean fetched,
|
||||||
|
LockMode lockMode,
|
||||||
|
final SqlAliasBase sqlAliasBase,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
final TableReference primaryTableReference = getEntityMappingType().createPrimaryTableReference(
|
final TableReference primaryTableReference = getEntityMappingType().createPrimaryTableReference(
|
||||||
sqlAliasBase,
|
sqlAliasBase,
|
||||||
sqlExpressionResolver,
|
sqlExpressionResolver,
|
||||||
creationContext
|
creationContext
|
||||||
);
|
);
|
||||||
|
|
||||||
final TableGroup tableGroup = new StandardTableGroup(
|
return new StandardTableGroup(
|
||||||
navigablePath,
|
navigablePath,
|
||||||
this,
|
this,
|
||||||
|
fetched,
|
||||||
lockMode,
|
lockMode,
|
||||||
primaryTableReference,
|
primaryTableReference,
|
||||||
false,
|
false,
|
||||||
|
@ -676,25 +849,6 @@ public class ToOneAttributeMapping
|
||||||
),
|
),
|
||||||
creationContext.getSessionFactory()
|
creationContext.getSessionFactory()
|
||||||
);
|
);
|
||||||
|
|
||||||
final TableReference lhsTableReference = lhs.resolveTableReference( identifyingColumnsTableExpression );
|
|
||||||
|
|
||||||
final TableGroupJoin tableGroupJoin = new TableGroupJoin(
|
|
||||||
navigablePath,
|
|
||||||
sqlAstJoinType,
|
|
||||||
tableGroup,
|
|
||||||
foreignKeyDescriptor.generateJoinPredicate(
|
|
||||||
lhsTableReference,
|
|
||||||
primaryTableReference,
|
|
||||||
sqlAstJoinType,
|
|
||||||
sqlExpressionResolver,
|
|
||||||
creationContext
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
lhs.addTableGroupJoin( tableGroupJoin );
|
|
||||||
|
|
||||||
return tableGroupJoin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -117,7 +117,7 @@ public class ColumnReference implements OrderingExpression, SequencePart {
|
||||||
final int tableNumber = abstractEntityPersister.determineTableNumberForColumn( columnExpression );
|
final int tableNumber = abstractEntityPersister.determineTableNumberForColumn( columnExpression );
|
||||||
final String tableName = abstractEntityPersister.getTableName( tableNumber );
|
final String tableName = abstractEntityPersister.getTableName( tableNumber );
|
||||||
|
|
||||||
return tableGroup.getTableReference( tableName );
|
return tableGroup.getTableReference( tableGroup.getNavigablePath(), tableName );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return tableGroup.getPrimaryTableReference();
|
return tableGroup.getPrimaryTableReference();
|
||||||
|
|
|
@ -16,7 +16,6 @@ import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
|
||||||
import org.hibernate.metamodel.model.domain.SimpleDomainType;
|
import org.hibernate.metamodel.model.domain.SimpleDomainType;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.query.sqm.SqmPathSource;
|
import org.hibernate.query.sqm.SqmPathSource;
|
||||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
|
||||||
import org.hibernate.query.sqm.internal.SqmMappingModelHelper;
|
import org.hibernate.query.sqm.internal.SqmMappingModelHelper;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
|
import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
|
||||||
|
@ -128,14 +127,14 @@ public abstract class AbstractPluralAttribute<D,C,E>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPath<E> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
|
public SqmPath<E> createSqmPath(SqmPath<?> lhs) {
|
||||||
final NavigablePath navigablePath = lhs.getNavigablePath().append( getPathName() );
|
final NavigablePath navigablePath = lhs.getNavigablePath().append( getPathName() );
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return new SqmPluralValuedSimplePath(
|
return new SqmPluralValuedSimplePath(
|
||||||
navigablePath,
|
navigablePath,
|
||||||
this,
|
this,
|
||||||
lhs,
|
lhs,
|
||||||
creationState.getCreationContext().getNodeBuilder()
|
lhs.nodeBuilder()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,10 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.model.domain.internal;
|
package org.hibernate.metamodel.model.domain.internal;
|
||||||
|
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
|
||||||
import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
|
import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
|
||||||
import org.hibernate.metamodel.model.domain.BasicDomainType;
|
import org.hibernate.metamodel.model.domain.BasicDomainType;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.query.sqm.SqmPathSource;
|
import org.hibernate.query.sqm.SqmPathSource;
|
||||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmAnyValuedSimplePath;
|
import org.hibernate.query.sqm.tree.domain.SqmAnyValuedSimplePath;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||||
|
|
||||||
|
@ -20,7 +19,7 @@ import static javax.persistence.metamodel.Bindable.BindableType.SINGULAR_ATTRIBU
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> {
|
public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> {
|
||||||
private SqmPathSource<?> keyPathSource;
|
private final SqmPathSource<?> keyPathSource;
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
public AnyMappingSqmPathSource(
|
public AnyMappingSqmPathSource(
|
||||||
|
@ -47,13 +46,9 @@ public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
|
public SqmPath<J> createSqmPath(SqmPath<?> lhs) {
|
||||||
return new SqmAnyValuedSimplePath<>(
|
final NavigablePath navigablePath = lhs.getNavigablePath().append( getPathName() );
|
||||||
lhs.getNavigablePath().append( getPathName() ),
|
return new SqmAnyValuedSimplePath( navigablePath, this, lhs, lhs.nodeBuilder() );
|
||||||
this,
|
|
||||||
lhs,
|
|
||||||
creationState.getCreationContext().getQueryEngine().getCriteriaBuilder()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import org.hibernate.metamodel.model.domain.BasicDomainType;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.query.sqm.IllegalPathUsageException;
|
import org.hibernate.query.sqm.IllegalPathUsageException;
|
||||||
import org.hibernate.query.sqm.SqmPathSource;
|
import org.hibernate.query.sqm.SqmPathSource;
|
||||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
|
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||||
|
|
||||||
|
@ -42,13 +41,13 @@ public class BasicSqmPathSource<J>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
|
public SqmPath<J> createSqmPath(SqmPath<?> lhs) {
|
||||||
final NavigablePath navigablePath = lhs.getNavigablePath().append( getPathName() );
|
final NavigablePath navigablePath = lhs.getNavigablePath().append( getPathName() );
|
||||||
return new SqmBasicValuedSimplePath<>(
|
return new SqmBasicValuedSimplePath<>(
|
||||||
navigablePath,
|
navigablePath,
|
||||||
this,
|
this,
|
||||||
lhs,
|
lhs,
|
||||||
creationState.getCreationContext().getNodeBuilder()
|
lhs.nodeBuilder()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ package org.hibernate.metamodel.model.domain.internal;
|
||||||
import org.hibernate.metamodel.model.domain.AllowableParameterType;
|
import org.hibernate.metamodel.model.domain.AllowableParameterType;
|
||||||
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
||||||
import org.hibernate.query.sqm.SqmPathSource;
|
import org.hibernate.query.sqm.SqmPathSource;
|
||||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmEmbeddedValuedSimplePath;
|
import org.hibernate.query.sqm.tree.domain.SqmEmbeddedValuedSimplePath;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||||
|
|
||||||
|
@ -49,12 +48,12 @@ public class EmbeddedSqmPathSource<J>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
|
public SqmPath<J> createSqmPath(SqmPath<?> lhs) {
|
||||||
return new SqmEmbeddedValuedSimplePath<>(
|
return new SqmEmbeddedValuedSimplePath<>(
|
||||||
lhs.getNavigablePath().append( getPathName() ),
|
lhs.getNavigablePath().append( getPathName() ),
|
||||||
this,
|
this,
|
||||||
lhs,
|
lhs,
|
||||||
creationState.getCreationContext().getNodeBuilder()
|
lhs.nodeBuilder()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
package org.hibernate.metamodel.model.domain.internal;
|
package org.hibernate.metamodel.model.domain.internal;
|
||||||
|
|
||||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
|
||||||
import org.hibernate.query.sqm.SqmPathSource;
|
import org.hibernate.query.sqm.SqmPathSource;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmEntityValuedSimplePath;
|
import org.hibernate.query.sqm.tree.domain.SqmEntityValuedSimplePath;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||||
|
@ -36,12 +35,12 @@ public class EntitySqmPathSource<J> extends AbstractSqmPathSource<J> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
|
public SqmPath<J> createSqmPath(SqmPath<?> lhs) {
|
||||||
return new SqmEntityValuedSimplePath<>(
|
return new SqmEntityValuedSimplePath<>(
|
||||||
lhs.getNavigablePath().append( getPathName() ),
|
lhs.getNavigablePath().append( getPathName() ),
|
||||||
this,
|
this,
|
||||||
lhs,
|
lhs,
|
||||||
creationState.getCreationContext().getNodeBuilder()
|
lhs.nodeBuilder()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
|
||||||
import org.hibernate.metamodel.model.domain.JpaMetamodel;
|
import org.hibernate.metamodel.model.domain.JpaMetamodel;
|
||||||
import org.hibernate.metamodel.model.domain.PersistentAttribute;
|
import org.hibernate.metamodel.model.domain.PersistentAttribute;
|
||||||
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
|
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
|
||||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
|
||||||
import org.hibernate.query.sqm.IllegalPathUsageException;
|
import org.hibernate.query.sqm.IllegalPathUsageException;
|
||||||
import org.hibernate.query.sqm.SqmPathSource;
|
import org.hibernate.query.sqm.SqmPathSource;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
|
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
|
||||||
|
@ -86,12 +85,12 @@ public class EntityTypeImpl<J>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPath<?> createSqmPath(SqmPath lhs, SqmCreationState creationState) {
|
public SqmPath<?> createSqmPath(SqmPath lhs) {
|
||||||
return new SqmBasicValuedSimplePath(
|
return new SqmBasicValuedSimplePath(
|
||||||
lhs.getNavigablePath().append( EntityDiscriminatorMapping.ROLE_NAME ),
|
lhs.getNavigablePath().append( EntityDiscriminatorMapping.ROLE_NAME ),
|
||||||
this,
|
this,
|
||||||
lhs,
|
lhs,
|
||||||
creationState.getCreationContext().getNodeBuilder()
|
lhs.nodeBuilder()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,8 +222,7 @@ public class EntityTypeImpl<J>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPath<J> createSqmPath(
|
public SqmPath<J> createSqmPath(
|
||||||
SqmPath<?> lhs,
|
SqmPath<?> lhs) {
|
||||||
SqmCreationState creationState) {
|
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException(
|
||||||
"EntityType cannot be used to create an SqmPath - that would be an SqmFrom which are created directly"
|
"EntityType cannot be used to create an SqmPath - that would be an SqmFrom which are created directly"
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,13 +6,10 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.model.domain.internal;
|
package org.hibernate.metamodel.model.domain.internal;
|
||||||
|
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
|
||||||
import org.hibernate.metamodel.model.domain.ManagedDomainType;
|
import org.hibernate.metamodel.model.domain.ManagedDomainType;
|
||||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
|
||||||
import org.hibernate.query.sqm.IllegalPathUsageException;
|
import org.hibernate.query.sqm.IllegalPathUsageException;
|
||||||
import org.hibernate.query.sqm.SqmPathSource;
|
import org.hibernate.query.sqm.SqmPathSource;
|
||||||
import org.hibernate.query.sqm.tree.domain.NonAggregatedCompositeSimplePath;
|
import org.hibernate.query.sqm.tree.domain.NonAggregatedCompositeSimplePath;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmEmbeddedValuedSimplePath;
|
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,12 +36,12 @@ public class NonAggregatedCompositeSqmPathSource extends AbstractSqmPathSource i
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPath createSqmPath(SqmPath lhs, SqmCreationState creationState) {
|
public SqmPath createSqmPath(SqmPath lhs) {
|
||||||
return new NonAggregatedCompositeSimplePath(
|
return new NonAggregatedCompositeSimplePath(
|
||||||
lhs.getNavigablePath().append( getPathName() ),
|
lhs.getNavigablePath().append( getPathName() ),
|
||||||
this,
|
this,
|
||||||
lhs,
|
lhs,
|
||||||
creationState.getCreationContext().getNodeBuilder()
|
lhs.nodeBuilder()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,10 +221,8 @@ public class SingularAttributeImpl<D,J>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPath<J> createSqmPath(
|
public SqmPath<J> createSqmPath(SqmPath lhs) {
|
||||||
SqmPath lhs,
|
return sqmPathSource.createSqmPath( lhs );
|
||||||
SqmCreationState creationState) {
|
|
||||||
return sqmPathSource.createSqmPath( lhs, creationState );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DelayedKeyTypeAccess implements Supplier<SimpleDomainType<J>>, Serializable {
|
private class DelayedKeyTypeAccess implements Supplier<SimpleDomainType<J>>, Serializable {
|
||||||
|
|
|
@ -1950,7 +1950,7 @@ public abstract class AbstractCollectionPersister
|
||||||
tableReference = tableGroup.getPrimaryTableReference();
|
tableReference = tableGroup.getPrimaryTableReference();
|
||||||
}
|
}
|
||||||
else if ( elementPersister instanceof Joinable ) {
|
else if ( elementPersister instanceof Joinable ) {
|
||||||
tableReference = tableGroup.getTableReference( ( (Joinable) elementPersister ).getTableName() );
|
tableReference = tableGroup.getTableReference( tableGroup.getNavigablePath(), ( (Joinable) elementPersister ).getTableName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( tableReference != null ) {
|
if ( tableReference != null ) {
|
||||||
|
|
|
@ -1267,7 +1267,7 @@ public abstract class AbstractEntityPersister
|
||||||
String resultVariable,
|
String resultVariable,
|
||||||
DomainResultCreationState creationState) {
|
DomainResultCreationState creationState) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return new EntityResultImpl( navigablePath, this, resultVariable, creationState );
|
return new EntityResultImpl( navigablePath, this, tableGroup, resultVariable, creationState );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -6613,6 +6613,7 @@ public abstract class AbstractEntityPersister
|
||||||
stateArrayPosition,
|
stateArrayPosition,
|
||||||
bootProperty,
|
bootProperty,
|
||||||
this,
|
this,
|
||||||
|
this,
|
||||||
(EntityType) attrType,
|
(EntityType) attrType,
|
||||||
propertyAccess,
|
propertyAccess,
|
||||||
tupleAttrDefinition.getCascadeStyle(),
|
tupleAttrDefinition.getCascadeStyle(),
|
||||||
|
|
|
@ -1294,7 +1294,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
DomainResultCreationState creationState) {
|
DomainResultCreationState creationState) {
|
||||||
if ( hasSubclasses() ) {
|
if ( hasSubclasses() ) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return new EntityResultJoinedSubclassImpl( navigablePath, this, resultVariable, creationState );
|
return new EntityResultJoinedSubclassImpl( navigablePath, this, tableGroup, resultVariable, creationState );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return super.createDomainResult( navigablePath, tableGroup, resultVariable, creationState );
|
return super.createDomainResult( navigablePath, tableGroup, resultVariable, creationState );
|
||||||
|
@ -1358,11 +1358,11 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
boolean addPrimaryTableCaseAsLastCaseExpression = false;
|
boolean addPrimaryTableCaseAsLastCaseExpression = false;
|
||||||
for ( String tableName : discriminatorValuesByTableName.keySet() ) {
|
for ( String tableName : discriminatorValuesByTableName.keySet() ) {
|
||||||
if ( !primaryTableReference.getTableExpression().equals( tableName ) ) {
|
if ( !primaryTableReference.getTableExpression().equals( tableName ) ) {
|
||||||
TableReference tableReference = entityTableGroup.getTableReference( tableName );
|
TableReference tableReference = entityTableGroup.getTableReference( entityTableGroup.getNavigablePath(), tableName );
|
||||||
if ( tableReference == null ) {
|
if ( tableReference == null ) {
|
||||||
// we have not yet created a TableReference for this sub-class table, but we need to because
|
// we have not yet created a TableReference for this sub-class table, but we need to because
|
||||||
// it has a discriminator value associated with it
|
// it has a discriminator value associated with it
|
||||||
tableReference = entityTableGroup.resolveTableReference( tableName );
|
tableReference = entityTableGroup.resolveTableReference( entityTableGroup.getNavigablePath(), tableName );
|
||||||
}
|
}
|
||||||
|
|
||||||
final ColumnReference identifierColumnReference = getIdentifierColumnReference( tableReference );
|
final ColumnReference identifierColumnReference = getIdentifierColumnReference( tableReference );
|
||||||
|
|
|
@ -51,9 +51,11 @@ import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
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.expression.QueryLiteral;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate;
|
import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate;
|
||||||
|
import org.hibernate.sql.ast.tree.predicate.InListPredicate;
|
||||||
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||||
import org.hibernate.type.AssociationType;
|
import org.hibernate.type.AssociationType;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
|
@ -636,7 +638,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
||||||
frag.addValues( decodeTreatAsRequests( treatAsDeclarations ) );
|
frag.addValues( decodeTreatAsRequests( treatAsDeclarations ) );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
frag.addValues( fullDiscriminatorValues() );
|
frag.addValues( fullDiscriminatorSQLValues() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return frag.toFragmentString();
|
return frag.toFragmentString();
|
||||||
|
@ -672,10 +674,11 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
||||||
return ArrayHelper.toStringArray( values );
|
return ArrayHelper.toStringArray( values );
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] fullDiscriminatorValues;
|
private String[] fullDiscriminatorSQLValues;
|
||||||
|
|
||||||
private String[] fullDiscriminatorValues() {
|
private String[] fullDiscriminatorSQLValues() {
|
||||||
if ( fullDiscriminatorValues == null ) {
|
String[] fullDiscriminatorSQLValues = this.fullDiscriminatorSQLValues;
|
||||||
|
if ( fullDiscriminatorSQLValues == null ) {
|
||||||
// first access; build it
|
// first access; build it
|
||||||
final List<String> values = new ArrayList<>();
|
final List<String> values = new ArrayList<>();
|
||||||
for ( String subclass : getSubclassClosure() ) {
|
for ( String subclass : getSubclassClosure() ) {
|
||||||
|
@ -684,7 +687,26 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
||||||
values.add( queryable.getDiscriminatorSQLValue() );
|
values.add( queryable.getDiscriminatorSQLValue() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fullDiscriminatorValues = ArrayHelper.toStringArray( values );
|
this.fullDiscriminatorSQLValues = fullDiscriminatorSQLValues = ArrayHelper.toStringArray( values );
|
||||||
|
}
|
||||||
|
|
||||||
|
return fullDiscriminatorSQLValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object[] fullDiscriminatorValues;
|
||||||
|
|
||||||
|
private Object[] fullDiscriminatorValues() {
|
||||||
|
Object[] fullDiscriminatorValues = this.fullDiscriminatorValues;
|
||||||
|
if ( fullDiscriminatorValues == null ) {
|
||||||
|
// first access; build it
|
||||||
|
final List<Object> values = new ArrayList<>();
|
||||||
|
for ( String subclass : getSubclassClosure() ) {
|
||||||
|
final Queryable queryable = (Queryable) getFactory().getMetamodel().entityPersister( subclass );
|
||||||
|
if ( !queryable.isAbstract() ) {
|
||||||
|
values.add( queryable.getDiscriminatorValue() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.fullDiscriminatorValues = fullDiscriminatorValues = values.toArray(new Object[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fullDiscriminatorValues;
|
return fullDiscriminatorValues;
|
||||||
|
@ -946,23 +968,34 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
||||||
getDiscriminatorColumnName()
|
getDiscriminatorColumnName()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final BasicType<?> discriminatorType = (BasicType<?>) getDiscriminatorType();
|
||||||
|
final Expression sqlExpression = sqlExpressionResolver.resolveSqlExpression(
|
||||||
|
columnReferenceKey,
|
||||||
|
sqlAstProcessingState -> new ColumnReference(
|
||||||
|
tableGroup.getPrimaryTableReference().getIdentificationVariable(),
|
||||||
|
discriminatorExpression,
|
||||||
|
isDiscriminatorFormula(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
(discriminatorType).getJdbcMapping(),
|
||||||
|
getFactory()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if ( hasSubclasses() ) {
|
||||||
|
final Object[] discriminatorValues = fullDiscriminatorValues();
|
||||||
|
final List<Expression> values = new ArrayList<>( discriminatorValues.length );
|
||||||
|
for ( Object discriminatorValue : discriminatorValues ) {
|
||||||
|
values.add( new QueryLiteral<>( discriminatorValue, discriminatorType ) );
|
||||||
|
}
|
||||||
|
return new InListPredicate( sqlExpression, values );
|
||||||
|
}
|
||||||
return new ComparisonPredicate(
|
return new ComparisonPredicate(
|
||||||
sqlExpressionResolver.resolveSqlExpression(
|
sqlExpression,
|
||||||
columnReferenceKey,
|
|
||||||
sqlAstProcessingState -> new ColumnReference(
|
|
||||||
tableGroup.getPrimaryTableReference().getIdentificationVariable(),
|
|
||||||
discriminatorExpression,
|
|
||||||
isDiscriminatorFormula(),
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
( (BasicType<?>) getDiscriminatorType() ).getJdbcMapping(),
|
|
||||||
getFactory()
|
|
||||||
)
|
|
||||||
),
|
|
||||||
ComparisonOperator.EQUAL,
|
ComparisonOperator.EQUAL,
|
||||||
new QueryLiteral<>(
|
new QueryLiteral<>(
|
||||||
getDiscriminatorValue(),
|
getDiscriminatorValue(),
|
||||||
( (BasicType<?>) getDiscriminatorType() )
|
discriminatorType
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,20 +139,12 @@ public class BasicDotIdentifierConsumer implements DotIdentifierConsumer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final SqmFrom pathRootByExposedNavigable = sqmPathRegistry.findFromExposing( identifier );
|
final SqmFrom<?, ?> pathRootByExposedNavigable = sqmPathRegistry.findFromExposing( identifier );
|
||||||
if ( pathRootByExposedNavigable != null ) {
|
if ( pathRootByExposedNavigable != null ) {
|
||||||
// identifier is an "unqualified attribute reference"
|
// identifier is an "unqualified attribute reference"
|
||||||
validateAsRoot( pathRootByExposedNavigable );
|
validateAsRoot( pathRootByExposedNavigable );
|
||||||
|
|
||||||
SqmPath sqmPath = pathRootByExposedNavigable.getImplicitJoinPath( identifier );
|
SqmPath<?> sqmPath = (SqmPath<?>) pathRootByExposedNavigable.get( identifier );
|
||||||
if ( sqmPath == null ) {
|
|
||||||
final SqmPathSource subPathSource = pathRootByExposedNavigable.getReferencedPathSource()
|
|
||||||
.findSubPathSource( identifier );
|
|
||||||
sqmPath = subPathSource.createSqmPath( pathRootByExposedNavigable, creationState );
|
|
||||||
if ( !isTerminal ) {
|
|
||||||
pathRootByExposedNavigable.registerImplicitJoinPath( sqmPath );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( isTerminal ) {
|
if ( isTerminal ) {
|
||||||
return sqmPath;
|
return sqmPath;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
package org.hibernate.query.hql.internal;
|
package org.hibernate.query.hql.internal;
|
||||||
|
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
import org.hibernate.query.SemanticException;
|
|
||||||
import org.hibernate.query.hql.HqlLogging;
|
import org.hibernate.query.hql.HqlLogging;
|
||||||
import org.hibernate.query.hql.spi.SemanticPathPart;
|
import org.hibernate.query.hql.spi.SemanticPathPart;
|
||||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
import org.hibernate.query.hql.spi.SqmCreationState;
|
||||||
|
@ -43,18 +42,6 @@ public class DomainPathPart implements SemanticPathPart {
|
||||||
currentPath,
|
currentPath,
|
||||||
name
|
name
|
||||||
);
|
);
|
||||||
final SqmPath<?> lhs = currentPath;
|
|
||||||
final SqmPathSource subPathSource = lhs.getReferencedPathSource().findSubPathSource( name );
|
|
||||||
if ( subPathSource == null ) {
|
|
||||||
throw new SemanticException( "Cannot resolve path (`" + name + "`) relative to `" + lhs.getNavigablePath() + "`" );
|
|
||||||
}
|
|
||||||
//noinspection unchecked
|
|
||||||
final SqmPath<?> existingImplicitJoinPath = lhs.getImplicitJoinPath( name );
|
|
||||||
if ( existingImplicitJoinPath != null ) {
|
|
||||||
currentPath = existingImplicitJoinPath;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we want to allow re-use of matched unaliased SqmFrom nodes
|
// if we want to allow re-use of matched unaliased SqmFrom nodes
|
||||||
//
|
//
|
||||||
// final SqmPathRegistry pathRegistry = creationState.getCurrentProcessingState().getPathRegistry();
|
// final SqmPathRegistry pathRegistry = creationState.getCurrentProcessingState().getPathRegistry();
|
||||||
|
@ -70,13 +57,11 @@ public class DomainPathPart implements SemanticPathPart {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
currentPath = (SqmPath<?>) currentPath.get( name );
|
||||||
currentPath = subPathSource.createSqmPath( lhs, creationState );
|
|
||||||
if ( isTerminal ) {
|
if ( isTerminal ) {
|
||||||
return currentPath;
|
return currentPath;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lhs.registerImplicitJoinPath( currentPath );
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1925,8 +1925,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
if ( sqmPathType instanceof IdentifiableDomainType ) {
|
if ( sqmPathType instanceof IdentifiableDomainType ) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
final SqmPath idPath = ( (IdentifiableDomainType) sqmPathType ).getIdentifierDescriptor().createSqmPath(
|
final SqmPath idPath = ( (IdentifiableDomainType) sqmPathType ).getIdentifierDescriptor().createSqmPath(
|
||||||
sqmPath,
|
sqmPath
|
||||||
this
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( ctx.pathContinuation() == null ) {
|
if ( ctx.pathContinuation() == null ) {
|
||||||
|
@ -1960,7 +1959,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
}
|
}
|
||||||
|
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return versionAttribute.createSqmPath( sqmPath, this );
|
return versionAttribute.createSqmPath( sqmPath );
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new SemanticException( "Path does not reference an identifiable-type : " + sqmPath.getNavigablePath().getFullPath() );
|
throw new SemanticException( "Path does not reference an identifiable-type : " + sqmPath.getNavigablePath().getFullPath() );
|
||||||
|
@ -3832,8 +3831,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
|
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return ( (PluralPersistentAttribute<?, ?, ?>) pluralAttribute ).getIndexPathSource().createSqmPath(
|
return ( (PluralPersistentAttribute<?, ?, ?>) pluralAttribute ).getIndexPathSource().createSqmPath(
|
||||||
sqmFrom,
|
sqmFrom
|
||||||
this
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4143,8 +4141,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
|
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
SqmPath result = attribute.getElementPathSource().createSqmPath(
|
SqmPath result = attribute.getElementPathSource().createSqmPath(
|
||||||
pluralAttributePath,
|
pluralAttributePath
|
||||||
this
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( ctx.pathContinuation() != null ) {
|
if ( ctx.pathContinuation() != null ) {
|
||||||
|
@ -4162,15 +4159,15 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
|
|
||||||
if ( sqmPath instanceof SqmMapJoin ) {
|
if ( sqmPath instanceof SqmMapJoin ) {
|
||||||
final SqmMapJoin sqmMapJoin = (SqmMapJoin) sqmPath;
|
final SqmMapJoin sqmMapJoin = (SqmMapJoin) sqmPath;
|
||||||
return sqmMapJoin.getReferencedPathSource().getIndexPathSource().createSqmPath( sqmMapJoin, this );
|
return sqmMapJoin.getReferencedPathSource().getIndexPathSource().createSqmPath( sqmMapJoin );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert sqmPath instanceof SqmPluralValuedSimplePath;
|
assert sqmPath instanceof SqmPluralValuedSimplePath;
|
||||||
final SqmPluralValuedSimplePath mapPath = (SqmPluralValuedSimplePath) sqmPath;
|
final SqmPluralValuedSimplePath mapPath = (SqmPluralValuedSimplePath) sqmPath;
|
||||||
final SqmPath keyPath = mapPath.getReferencedPathSource()
|
final SqmPath keyPath = mapPath.getReferencedPathSource()
|
||||||
.getIndexPathSource()
|
.getIndexPathSource()
|
||||||
.createSqmPath( mapPath, this );
|
.createSqmPath( mapPath );
|
||||||
mapPath.registerImplicitJoinPath( keyPath );
|
mapPath.registerReusablePath( keyPath );
|
||||||
return keyPath;
|
return keyPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,6 @@ import org.hibernate.query.spi.QueryParameterBindings;
|
||||||
import org.hibernate.query.spi.QueryParameterImplementor;
|
import org.hibernate.query.spi.QueryParameterImplementor;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypedExpressable;
|
import org.hibernate.type.descriptor.java.JavaTypedExpressable;
|
||||||
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
|
||||||
import org.hibernate.type.descriptor.java.MutabilityPlanExposer;
|
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,7 +92,7 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"WeakerAccess" })
|
@SuppressWarnings({"WeakerAccess" })
|
||||||
protected QueryParameterBinding<?> makeBinding(QueryParameterImplementor<?> queryParameter) {
|
protected <T> QueryParameterBinding<T> makeBinding(QueryParameterImplementor<T> queryParameter) {
|
||||||
if ( parameterBindingMap == null ) {
|
if ( parameterBindingMap == null ) {
|
||||||
parameterBindingMap = new IdentityHashMap<>();
|
parameterBindingMap = new IdentityHashMap<>();
|
||||||
}
|
}
|
||||||
|
@ -108,7 +106,7 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final QueryParameterBinding<?> binding = new QueryParameterBindingImpl<>( queryParameter, sessionFactory, null, queryParametersValidationEnabled );
|
final QueryParameterBinding<T> binding = new QueryParameterBindingImpl<>( queryParameter, sessionFactory, null, queryParametersValidationEnabled );
|
||||||
parameterBindingMap.put( queryParameter, binding );
|
parameterBindingMap.put( queryParameter, binding );
|
||||||
|
|
||||||
return binding;
|
return binding;
|
||||||
|
@ -122,8 +120,7 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings {
|
||||||
@Override
|
@Override
|
||||||
public <P> QueryParameterBinding<P> getBinding(QueryParameterImplementor<P> parameter) {
|
public <P> QueryParameterBinding<P> getBinding(QueryParameterImplementor<P> parameter) {
|
||||||
if ( parameterBindingMap == null ) {
|
if ( parameterBindingMap == null ) {
|
||||||
//noinspection unchecked
|
return makeBinding( parameter );
|
||||||
return (QueryParameterBinding<P>) makeBinding( parameter );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryParameterBinding<?> binding = parameterBindingMap.get( parameter );
|
QueryParameterBinding<?> binding = parameterBindingMap.get( parameter );
|
||||||
|
|
|
@ -315,7 +315,7 @@ public class DomainResultCreationStateImpl
|
||||||
|
|
||||||
final Consumer<Fetchable> fetchableConsumer = fetchable -> {
|
final Consumer<Fetchable> fetchableConsumer = fetchable -> {
|
||||||
final String fetchableName = fetchable.getFetchableName();
|
final String fetchableName = fetchable.getFetchableName();
|
||||||
final NavigablePath fetchPath = fetchParent.getNavigablePath().append( fetchableName );
|
final NavigablePath fetchPath = fetchParent.resolveNavigablePath( fetchable );
|
||||||
final NavigablePath relativePath = relativePathStack.isEmpty()
|
final NavigablePath relativePath = relativePathStack.isEmpty()
|
||||||
? new NavigablePath( fetchableName )
|
? new NavigablePath( fetchableName )
|
||||||
: relativePathStack.getCurrent().append( fetchableName );
|
: relativePathStack.getCurrent().append( fetchableName );
|
||||||
|
|
|
@ -9,7 +9,6 @@ package org.hibernate.query.results;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
@ -113,18 +112,12 @@ public class TableGroupImpl implements TableGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference resolveTableReference(
|
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
String tableExpression, Supplier<TableReference> creator) {
|
|
||||||
return primaryTableReference;
|
return primaryTableReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference resolveTableReference(String tableExpression) {
|
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
return primaryTableReference;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableReference getTableReference(String tableExpression) {
|
|
||||||
return primaryTableReference;
|
return primaryTableReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ public class CompleteFetchBuilderBasicPart implements CompleteFetchBuilder, Mode
|
||||||
final String mappedColumn = referencedModelPart.getSelectionExpression();
|
final String mappedColumn = referencedModelPart.getSelectionExpression();
|
||||||
|
|
||||||
final TableGroup tableGroup = creationState.getFromClauseAccess().getTableGroup( parent.getNavigablePath() );
|
final TableGroup tableGroup = creationState.getFromClauseAccess().getTableGroup( parent.getNavigablePath() );
|
||||||
final TableReference tableReference = tableGroup.getTableReference( mappedTable );
|
final TableReference tableReference = tableGroup.getTableReference( navigablePath, mappedTable );
|
||||||
|
|
||||||
final String selectedAlias;
|
final String selectedAlias;
|
||||||
final int jdbcPosition;
|
final int jdbcPosition;
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class CompleteResultBuilderBasicModelPart
|
||||||
final DomainResultCreationStateImpl creationStateImpl = impl( domainResultCreationState );
|
final DomainResultCreationStateImpl creationStateImpl = impl( domainResultCreationState );
|
||||||
|
|
||||||
final TableGroup tableGroup = creationStateImpl.getFromClauseAccess().getTableGroup( navigablePath.getParent() );
|
final TableGroup tableGroup = creationStateImpl.getFromClauseAccess().getTableGroup( navigablePath.getParent() );
|
||||||
final TableReference tableReference = tableGroup.getTableReference( modelPart.getContainingTableExpression() );
|
final TableReference tableReference = tableGroup.getTableReference( navigablePath, modelPart.getContainingTableExpression() );
|
||||||
final String mappedColumn = modelPart.getSelectionExpression();
|
final String mappedColumn = modelPart.getSelectionExpression();
|
||||||
|
|
||||||
final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( columnAlias );
|
final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( columnAlias );
|
||||||
|
|
|
@ -59,7 +59,7 @@ public class ImplicitFetchBuilderBasic implements ImplicitFetchBuilder {
|
||||||
final int valuesArrayPosition = jdbcPositionToValuesArrayPosition( jdbcPosition );
|
final int valuesArrayPosition = jdbcPositionToValuesArrayPosition( jdbcPosition );
|
||||||
|
|
||||||
final Expression expression = creationStateImpl.resolveSqlExpression(
|
final Expression expression = creationStateImpl.resolveSqlExpression(
|
||||||
createColumnReferenceKey( parentTableGroup.getTableReference( table ), column ),
|
createColumnReferenceKey( parentTableGroup.getTableReference( fetchPath, table ), column ),
|
||||||
processingState -> new SqlSelectionImpl( valuesArrayPosition, fetchable )
|
processingState -> new SqlSelectionImpl( valuesArrayPosition, fetchable )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -17,13 +17,10 @@ import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.query.results.Builders;
|
import org.hibernate.query.results.Builders;
|
||||||
import org.hibernate.query.results.DomainResultCreationStateImpl;
|
import org.hibernate.query.results.DomainResultCreationStateImpl;
|
||||||
import org.hibernate.query.results.FetchBuilder;
|
import org.hibernate.query.results.FetchBuilder;
|
||||||
import org.hibernate.query.results.SqlSelectionImpl;
|
|
||||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||||
import org.hibernate.sql.ast.SqlAstJoinType;
|
import org.hibernate.sql.ast.SqlAstJoinType;
|
||||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
import org.hibernate.sql.results.graph.FetchParent;
|
import org.hibernate.sql.results.graph.FetchParent;
|
||||||
|
@ -31,7 +28,6 @@ import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
|
||||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
||||||
|
|
||||||
import static org.hibernate.query.results.ResultsHelper.impl;
|
import static org.hibernate.query.results.ResultsHelper.impl;
|
||||||
import static org.hibernate.query.results.ResultsHelper.jdbcPositionToValuesArrayPosition;
|
|
||||||
import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey;
|
import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,6 +88,7 @@ public class ImplicitFetchBuilderEmbeddable implements ImplicitFetchBuilder {
|
||||||
parentTableGroup,
|
parentTableGroup,
|
||||||
null,
|
null,
|
||||||
SqlAstJoinType.INNER,
|
SqlAstJoinType.INNER,
|
||||||
|
true,
|
||||||
LockMode.READ,
|
LockMode.READ,
|
||||||
creationStateImpl
|
creationStateImpl
|
||||||
);
|
);
|
||||||
|
|
|
@ -65,6 +65,7 @@ public class ImplicitModelPartResultBuilderEmbeddable
|
||||||
parentTableGroup,
|
parentTableGroup,
|
||||||
null,
|
null,
|
||||||
SqlAstJoinType.INNER,
|
SqlAstJoinType.INNER,
|
||||||
|
true,
|
||||||
LockMode.READ,
|
LockMode.READ,
|
||||||
creationStateImpl
|
creationStateImpl
|
||||||
);
|
);
|
||||||
|
|
|
@ -720,7 +720,7 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
||||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||||
public Set<Parameter<?>> getParameters() {
|
public Set<Parameter<?>> getParameters() {
|
||||||
getSession().checkOpen( false );
|
getSession().checkOpen( false );
|
||||||
return (Set) ( (ParameterMetadata) getParameterMetadata() ).getRegistrations();
|
return (Set) getParameterMetadata().getRegistrations();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -821,16 +821,16 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
||||||
return getQueryParameterBindings().getBinding( parameter );
|
return getQueryParameterBindings().getBinding( parameter );
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings( {"WeakerAccess", "unchecked"} )
|
@SuppressWarnings( {"WeakerAccess"} )
|
||||||
protected <P> QueryParameterBinding<P> locateBinding(String name) {
|
protected <P> QueryParameterBinding<P> locateBinding(String name) {
|
||||||
getSession().checkOpen();
|
getSession().checkOpen();
|
||||||
return (QueryParameterBinding<P>) getQueryParameterBindings().getBinding( name );
|
return getQueryParameterBindings().getBinding( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings( {"WeakerAccess", "unchecked"} )
|
@SuppressWarnings( {"WeakerAccess"} )
|
||||||
protected <P> QueryParameterBinding<P> locateBinding(int position) {
|
protected <P> QueryParameterBinding<P> locateBinding(int position) {
|
||||||
getSession().checkOpen();
|
getSession().checkOpen();
|
||||||
return (QueryParameterBinding<P>) getQueryParameterBindings().getBinding( position );
|
return getQueryParameterBindings().getBinding( position );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -45,7 +45,7 @@ public interface SqmPathSource<J> extends SqmExpressable<J>, Bindable<J> {
|
||||||
/**
|
/**
|
||||||
* Create an SQM path for this source relative to the given left-hand side
|
* Create an SQM path for this source relative to the given left-hand side
|
||||||
*/
|
*/
|
||||||
SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState);
|
SqmPath<J> createSqmPath(SqmPath<?> lhs);
|
||||||
|
|
||||||
default <X extends DomainType> X sqmAs(Class<X> targetType) {
|
default <X extends DomainType> X sqmAs(Class<X> targetType) {
|
||||||
if ( targetType.isInstance( this ) ) {
|
if ( targetType.isInstance( this ) ) {
|
||||||
|
|
|
@ -231,7 +231,9 @@ public class QuerySqmImpl<R>
|
||||||
final Object value = jpaCriteriaParameter.getValue();
|
final Object value = jpaCriteriaParameter.getValue();
|
||||||
// We don't set a null value, unless the type is also null which is the case when using HibernateCriteriaBuilder.value
|
// We don't set a null value, unless the type is also null which is the case when using HibernateCriteriaBuilder.value
|
||||||
if ( value != null || jpaCriteriaParameter.getNodeType() == null ) {
|
if ( value != null || jpaCriteriaParameter.getNodeType() == null ) {
|
||||||
setParameter( jpaCriteriaParameter, value );
|
// Use the anticipated type for binding the value if possible
|
||||||
|
getQueryParameterBindings().getBinding( jpaCriteriaParameter )
|
||||||
|
.setBindValue( value, jpaCriteriaParameter.getAnticipatedType() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,10 @@ public class MatchingIdSelectionHelper {
|
||||||
|
|
||||||
targetEntityDescriptor.getIdentifierMapping().forEachSelectable(
|
targetEntityDescriptor.getIdentifierMapping().forEachSelectable(
|
||||||
(position, selection) -> {
|
(position, selection) -> {
|
||||||
final TableReference tableReference = mutatingTableGroup.resolveTableReference( selection.getContainingTableExpression() );
|
final TableReference tableReference = mutatingTableGroup.resolveTableReference(
|
||||||
|
mutatingTableGroup.getNavigablePath(),
|
||||||
|
selection.getContainingTableExpression()
|
||||||
|
);
|
||||||
final Expression expression = sqmConverter.getSqlExpressionResolver().resolveSqlExpression(
|
final Expression expression = sqmConverter.getSqlExpressionResolver().resolveSqlExpression(
|
||||||
SqlExpressionResolver.createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
|
SqlExpressionResolver.createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
|
||||||
sqlAstProcessingState -> new ColumnReference(
|
sqlAstProcessingState -> new ColumnReference(
|
||||||
|
@ -153,7 +156,10 @@ public class MatchingIdSelectionHelper {
|
||||||
|
|
||||||
targetEntityDescriptor.getIdentifierMapping().forEachSelectable(
|
targetEntityDescriptor.getIdentifierMapping().forEachSelectable(
|
||||||
(position, selection) -> {
|
(position, selection) -> {
|
||||||
final TableReference tableReference = mutatingTableGroup.resolveTableReference( selection.getContainingTableExpression() );
|
final TableReference tableReference = mutatingTableGroup.resolveTableReference(
|
||||||
|
mutatingTableGroup.getNavigablePath(),
|
||||||
|
selection.getContainingTableExpression()
|
||||||
|
);
|
||||||
final Expression expression = sqmConverter.getSqlExpressionResolver().resolveSqlExpression(
|
final Expression expression = sqmConverter.getSqlExpressionResolver().resolveSqlExpression(
|
||||||
SqlExpressionResolver.createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
|
SqlExpressionResolver.createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
|
||||||
sqlAstProcessingState -> new ColumnReference(
|
sqlAstProcessingState -> new ColumnReference(
|
||||||
|
|
|
@ -101,7 +101,10 @@ public class CteDeleteHandler extends AbstractCteMutationHandler implements Dele
|
||||||
idSelectCte.getCteTable().getCteColumns(),
|
idSelectCte.getCteTable().getCteColumns(),
|
||||||
factory
|
factory
|
||||||
);
|
);
|
||||||
final TableReference dmlTableReference = updatingTableGroup.resolveTableReference( tableExpression );
|
final TableReference dmlTableReference = updatingTableGroup.resolveTableReference(
|
||||||
|
updatingTableGroup.getNavigablePath(),
|
||||||
|
tableExpression
|
||||||
|
);
|
||||||
final List<ColumnReference> columnReferences = new ArrayList<>( idSelectCte.getCteTable().getCteColumns().size() );
|
final List<ColumnReference> columnReferences = new ArrayList<>( idSelectCte.getCteTable().getCteColumns().size() );
|
||||||
tableColumnsVisitationSupplier.get().accept(
|
tableColumnsVisitationSupplier.get().accept(
|
||||||
(index, selectable) -> columnReferences.add(
|
(index, selectable) -> columnReferences.add(
|
||||||
|
|
|
@ -69,7 +69,10 @@ public class CteUpdateHandler extends AbstractCteMutationHandler implements Upda
|
||||||
final EntityPersister rootEntityDescriptor = factory.getDomainModel().getEntityDescriptor( rootEntityName );
|
final EntityPersister rootEntityDescriptor = factory.getDomainModel().getEntityDescriptor( rootEntityName );
|
||||||
|
|
||||||
final String hierarchyRootTableName = ( (Joinable) rootEntityDescriptor ).getTableName();
|
final String hierarchyRootTableName = ( (Joinable) rootEntityDescriptor ).getTableName();
|
||||||
final TableReference hierarchyRootTableReference = updatingTableGroup.resolveTableReference( hierarchyRootTableName );
|
final TableReference hierarchyRootTableReference = updatingTableGroup.resolveTableReference(
|
||||||
|
updatingTableGroup.getNavigablePath(),
|
||||||
|
hierarchyRootTableName
|
||||||
|
);
|
||||||
assert hierarchyRootTableReference != null;
|
assert hierarchyRootTableReference != null;
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -144,7 +147,10 @@ public class CteUpdateHandler extends AbstractCteMutationHandler implements Upda
|
||||||
if ( assignmentList == null ) {
|
if ( assignmentList == null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final TableReference dmlTableReference = updatingTableGroup.resolveTableReference( tableExpression );
|
final TableReference dmlTableReference = updatingTableGroup.resolveTableReference(
|
||||||
|
updatingTableGroup.getNavigablePath(),
|
||||||
|
tableExpression
|
||||||
|
);
|
||||||
final List<ColumnReference> columnReferences = new ArrayList<>( idSelectCte.getCteTable().getCteColumns().size() );
|
final List<ColumnReference> columnReferences = new ArrayList<>( idSelectCte.getCteTable().getCteColumns().size() );
|
||||||
tableColumnsVisitationSupplier.get().accept(
|
tableColumnsVisitationSupplier.get().accept(
|
||||||
(index, selectable) -> columnReferences.add(
|
(index, selectable) -> columnReferences.add(
|
||||||
|
|
|
@ -87,7 +87,10 @@ public final class ExecuteWithIdTableHelper {
|
||||||
|
|
||||||
mutatingEntityDescriptor.getIdentifierMapping().forEachSelectable(
|
mutatingEntityDescriptor.getIdentifierMapping().forEachSelectable(
|
||||||
(jdbcPosition, selection) -> {
|
(jdbcPosition, selection) -> {
|
||||||
final TableReference tableReference = mutatingTableGroup.resolveTableReference( selection.getContainingTableExpression() );
|
final TableReference tableReference = mutatingTableGroup.resolveTableReference(
|
||||||
|
mutatingTableGroup.getNavigablePath(),
|
||||||
|
selection.getContainingTableExpression()
|
||||||
|
);
|
||||||
matchingIdSelection.getSelectClause().addSqlSelection(
|
matchingIdSelection.getSelectClause().addSqlSelection(
|
||||||
new SqlSelectionImpl(
|
new SqlSelectionImpl(
|
||||||
jdbcPosition,
|
jdbcPosition,
|
||||||
|
|
|
@ -124,7 +124,10 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle
|
||||||
|
|
||||||
final TableGroup deletingTableGroup = converter.getMutatingTableGroup();
|
final TableGroup deletingTableGroup = converter.getMutatingTableGroup();
|
||||||
|
|
||||||
final TableReference hierarchyRootTableReference = deletingTableGroup.resolveTableReference( hierarchyRootTableName );
|
final TableReference hierarchyRootTableReference = deletingTableGroup.resolveTableReference(
|
||||||
|
deletingTableGroup.getNavigablePath(),
|
||||||
|
hierarchyRootTableName
|
||||||
|
);
|
||||||
assert hierarchyRootTableReference != null;
|
assert hierarchyRootTableReference != null;
|
||||||
|
|
||||||
final Map<SqmParameter, List<List<JdbcParameter>>> parameterResolutions;
|
final Map<SqmParameter, List<List<JdbcParameter>>> parameterResolutions;
|
||||||
|
@ -213,7 +216,10 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle
|
||||||
final MutableInteger rows = new MutableInteger();
|
final MutableInteger rows = new MutableInteger();
|
||||||
|
|
||||||
final String rootTableName = ( (Joinable) rootEntityPersister ).getTableName();
|
final String rootTableName = ( (Joinable) rootEntityPersister ).getTableName();
|
||||||
final TableReference rootTableReference = tableGroup.resolveTableReference( rootTableName );
|
final TableReference rootTableReference = tableGroup.resolveTableReference(
|
||||||
|
tableGroup.getNavigablePath(),
|
||||||
|
rootTableName
|
||||||
|
);
|
||||||
|
|
||||||
final QuerySpec matchingIdSubQuerySpec = ExecuteWithoutIdTableHelper.createIdMatchingSubQuerySpec(
|
final QuerySpec matchingIdSubQuerySpec = ExecuteWithoutIdTableHelper.createIdMatchingSubQuerySpec(
|
||||||
tableGroup.getNavigablePath(),
|
tableGroup.getNavigablePath(),
|
||||||
|
@ -251,7 +257,7 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
deleteFromNonRootTableWithoutIdTable(
|
deleteFromNonRootTableWithoutIdTable(
|
||||||
tableGroup.resolveTableReference( tableExpression ),
|
tableGroup.resolveTableReference( tableGroup.getNavigablePath(), tableExpression ),
|
||||||
tableKeyColumnVisitationSupplier,
|
tableKeyColumnVisitationSupplier,
|
||||||
sqlExpressionResolver,
|
sqlExpressionResolver,
|
||||||
tableGroup,
|
tableGroup,
|
||||||
|
|
|
@ -133,7 +133,10 @@ public class TableBasedUpdateHandler
|
||||||
|
|
||||||
final TableGroup updatingTableGroup = converterDelegate.getMutatingTableGroup();
|
final TableGroup updatingTableGroup = converterDelegate.getMutatingTableGroup();
|
||||||
|
|
||||||
final TableReference hierarchyRootTableReference = updatingTableGroup.resolveTableReference( hierarchyRootTableName );
|
final TableReference hierarchyRootTableReference = updatingTableGroup.resolveTableReference(
|
||||||
|
updatingTableGroup.getNavigablePath(),
|
||||||
|
hierarchyRootTableName
|
||||||
|
);
|
||||||
assert hierarchyRootTableReference != null;
|
assert hierarchyRootTableReference != null;
|
||||||
|
|
||||||
final Map<SqmParameter, List<List<JdbcParameter>>> parameterResolutions;
|
final Map<SqmParameter, List<List<JdbcParameter>>> parameterResolutions;
|
||||||
|
|
|
@ -211,7 +211,10 @@ public class UpdateExecutionDelegate implements TableBasedUpdateHandler.Executio
|
||||||
return tableReferenceByQualifier;
|
return tableReferenceByQualifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
final TableReference tableReferenceByName = updatingTableGroup.resolveTableReference( columnReference.getQualifier() );
|
final TableReference tableReferenceByName = updatingTableGroup.resolveTableReference(
|
||||||
|
updatingTableGroup.getNavigablePath(),
|
||||||
|
columnReference.getQualifier()
|
||||||
|
);
|
||||||
if ( tableReferenceByName != null ) {
|
if ( tableReferenceByName != null ) {
|
||||||
return tableReferenceByName;
|
return tableReferenceByName;
|
||||||
}
|
}
|
||||||
|
@ -224,7 +227,7 @@ public class UpdateExecutionDelegate implements TableBasedUpdateHandler.Executio
|
||||||
Supplier<Consumer<SelectableConsumer>> tableKeyColumnVisitationSupplier,
|
Supplier<Consumer<SelectableConsumer>> tableKeyColumnVisitationSupplier,
|
||||||
QuerySpec idTableSubQuery,
|
QuerySpec idTableSubQuery,
|
||||||
ExecutionContext executionContext) {
|
ExecutionContext executionContext) {
|
||||||
final TableReference updatingTableReference = updatingTableGroup.resolveTableReference( tableExpression );
|
final TableReference updatingTableReference = updatingTableGroup.resolveTableReference( updatingTableGroup.getNavigablePath(), tableExpression );
|
||||||
|
|
||||||
final List<Assignment> assignments = assignmentsByTable.get( updatingTableReference );
|
final List<Assignment> assignments = assignmentsByTable.get( updatingTableReference );
|
||||||
if ( assignments == null || assignments.isEmpty() ) {
|
if ( assignments == null || assignments.isEmpty() ) {
|
||||||
|
|
|
@ -646,11 +646,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyManipulationImplicitJoins(SqmPath<?> sqmPath, TableGroup correspondingTableGroup) {
|
private void applyManipulationImplicitJoins(SqmPath<?> sqmPath, TableGroup correspondingTableGroup) {
|
||||||
consumeImplicitJoins(
|
consumeReusablePaths( sqmPath, correspondingTableGroup, BaseSqmToSqlAstConverter::verifyManipulationImplicitJoin );
|
||||||
sqmPath,
|
|
||||||
correspondingTableGroup,
|
|
||||||
BaseSqmToSqlAstConverter::verifyManipulationImplicitJoin
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void verifyManipulationImplicitJoin(SqmPath<?> joinedPath) {
|
private static void verifyManipulationImplicitJoin(SqmPath<?> joinedPath) {
|
||||||
|
@ -1772,7 +1768,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
log.tracef( "Resolved SqmRoot [%s] to correlated TableGroup [%s]", sqmRoot, tableGroup );
|
log.tracef( "Resolved SqmRoot [%s] to correlated TableGroup [%s]", sqmRoot, tableGroup );
|
||||||
|
|
||||||
consumeExplicitJoins( sqmRoot, tableGroup );
|
consumeExplicitJoins( sqmRoot, tableGroup );
|
||||||
consumeImplicitJoins( sqmRoot, tableGroup );
|
consumeReusablePaths( sqmRoot, tableGroup );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1786,6 +1782,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
creationContext
|
creationContext
|
||||||
);
|
);
|
||||||
final EntityIdentifierMapping identifierMapping = entityDescriptor.getIdentifierMapping();
|
final EntityIdentifierMapping identifierMapping = entityDescriptor.getIdentifierMapping();
|
||||||
|
final NavigablePath navigablePath = sqmRoot.getNavigablePath().append( identifierMapping.getNavigableRole().getNavigableName() );
|
||||||
final int jdbcTypeCount = identifierMapping.getJdbcTypeCount();
|
final int jdbcTypeCount = identifierMapping.getJdbcTypeCount();
|
||||||
if ( jdbcTypeCount == 1 ) {
|
if ( jdbcTypeCount == 1 ) {
|
||||||
identifierMapping.forEachSelectable(
|
identifierMapping.forEachSelectable(
|
||||||
|
@ -1793,13 +1790,13 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
additionalRestrictions,
|
additionalRestrictions,
|
||||||
new ComparisonPredicate(
|
new ComparisonPredicate(
|
||||||
new ColumnReference(
|
new ColumnReference(
|
||||||
parentTableGroup.getTableReference( selectable.getContainingTableExpression() ),
|
parentTableGroup.getTableReference( navigablePath, selectable.getContainingTableExpression() ),
|
||||||
selectable,
|
selectable,
|
||||||
sessionFactory
|
sessionFactory
|
||||||
),
|
),
|
||||||
ComparisonOperator.EQUAL,
|
ComparisonOperator.EQUAL,
|
||||||
new ColumnReference(
|
new ColumnReference(
|
||||||
tableGroup.getTableReference( selectable.getContainingTableExpression() ),
|
tableGroup.getTableReference( navigablePath, selectable.getContainingTableExpression() ),
|
||||||
selectable,
|
selectable,
|
||||||
sessionFactory
|
sessionFactory
|
||||||
)
|
)
|
||||||
|
@ -1814,14 +1811,14 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
(index, selectable) -> {
|
(index, selectable) -> {
|
||||||
lhs.add(
|
lhs.add(
|
||||||
new ColumnReference(
|
new ColumnReference(
|
||||||
parentTableGroup.getTableReference( selectable.getContainingTableExpression() ),
|
parentTableGroup.getTableReference( navigablePath, selectable.getContainingTableExpression() ),
|
||||||
selectable,
|
selectable,
|
||||||
sessionFactory
|
sessionFactory
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
rhs.add(
|
rhs.add(
|
||||||
new ColumnReference(
|
new ColumnReference(
|
||||||
tableGroup.getTableReference( selectable.getContainingTableExpression() ),
|
tableGroup.getTableReference( navigablePath, selectable.getContainingTableExpression() ),
|
||||||
selectable,
|
selectable,
|
||||||
sessionFactory
|
sessionFactory
|
||||||
)
|
)
|
||||||
|
@ -1860,7 +1857,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
currentQuerySpec().getFromClause().addRoot( tableGroup );
|
currentQuerySpec().getFromClause().addRoot( tableGroup );
|
||||||
|
|
||||||
consumeExplicitJoins( sqmRoot, tableGroup );
|
consumeExplicitJoins( sqmRoot, tableGroup );
|
||||||
consumeImplicitJoins( sqmRoot, tableGroup );
|
consumeReusablePaths( sqmRoot, tableGroup );
|
||||||
}
|
}
|
||||||
|
|
||||||
private EntityPersister resolveEntityPersister(EntityDomainType<?> entityDomainType) {
|
private EntityPersister resolveEntityPersister(EntityDomainType<?> entityDomainType) {
|
||||||
|
@ -1929,6 +1926,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
lhsTableGroup,
|
lhsTableGroup,
|
||||||
sqmJoin.getExplicitAlias(),
|
sqmJoin.getExplicitAlias(),
|
||||||
sqmJoin.getSqmJoinType().getCorrespondingSqlJoinType(),
|
sqmJoin.getSqmJoinType().getCorrespondingSqlJoinType(),
|
||||||
|
sqmJoin.isFetched(),
|
||||||
determineLockMode( sqmJoin.getExplicitAlias() ),
|
determineLockMode( sqmJoin.getExplicitAlias() ),
|
||||||
this
|
this
|
||||||
);
|
);
|
||||||
|
@ -1943,6 +1941,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
lhsTableGroup,
|
lhsTableGroup,
|
||||||
sqmJoin.getExplicitAlias(),
|
sqmJoin.getExplicitAlias(),
|
||||||
sqmJoin.getSqmJoinType().getCorrespondingSqlJoinType(),
|
sqmJoin.getSqmJoinType().getCorrespondingSqlJoinType(),
|
||||||
|
sqmJoin.isFetched(),
|
||||||
determineLockMode( sqmJoin.getExplicitAlias() ),
|
determineLockMode( sqmJoin.getExplicitAlias() ),
|
||||||
this
|
this
|
||||||
);
|
);
|
||||||
|
@ -1969,7 +1968,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
}
|
}
|
||||||
|
|
||||||
consumeExplicitJoins( sqmJoin, joinedTableGroup );
|
consumeExplicitJoins( sqmJoin, joinedTableGroup );
|
||||||
consumeImplicitJoins( sqmJoin, joinedTableGroup );
|
consumeReusablePaths( sqmJoin, joinedTableGroup );
|
||||||
}
|
}
|
||||||
|
|
||||||
private NavigablePath getJoinNavigablePath(
|
private NavigablePath getJoinNavigablePath(
|
||||||
|
@ -2015,7 +2014,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
getFromClauseIndex().register( sqmJoin, tableGroup );
|
getFromClauseIndex().register( sqmJoin, tableGroup );
|
||||||
|
|
||||||
consumeExplicitJoins( sqmJoin, tableGroupJoin.getJoinedGroup() );
|
consumeExplicitJoins( sqmJoin, tableGroupJoin.getJoinedGroup() );
|
||||||
consumeImplicitJoins( sqmJoin, tableGroupJoin.getJoinedGroup() );
|
consumeReusablePaths( sqmJoin, tableGroupJoin.getJoinedGroup() );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void consumeEntityJoin(SqmEntityJoin sqmJoin, TableGroup lhsTableGroup) {
|
private void consumeEntityJoin(SqmEntityJoin sqmJoin, TableGroup lhsTableGroup) {
|
||||||
|
@ -2043,7 +2042,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
lhsTableGroup.addTableGroupJoin( tableGroupJoin );
|
lhsTableGroup.addTableGroupJoin( tableGroupJoin );
|
||||||
|
|
||||||
consumeExplicitJoins( sqmJoin, tableGroupJoin.getJoinedGroup() );
|
consumeExplicitJoins( sqmJoin, tableGroupJoin.getJoinedGroup() );
|
||||||
consumeImplicitJoins( sqmJoin, tableGroupJoin.getJoinedGroup() );
|
consumeReusablePaths( sqmJoin, tableGroupJoin.getJoinedGroup() );
|
||||||
|
|
||||||
// add any additional join restrictions
|
// add any additional join restrictions
|
||||||
if ( sqmJoin.getJoinPredicate() != null ) {
|
if ( sqmJoin.getJoinPredicate() != null ) {
|
||||||
|
@ -2054,58 +2053,58 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void consumeImplicitJoins(SqmPath<?> sqmPath, TableGroup tableGroup) {
|
private void consumeReusablePaths(SqmPath<?> sqmPath, TableGroup tableGroup) {
|
||||||
consumeImplicitJoins(
|
consumeReusablePaths( sqmPath, tableGroup, (sqmSubPath) -> {} );
|
||||||
sqmPath,
|
|
||||||
tableGroup,
|
|
||||||
(sqmSubPath) -> {}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void consumeImplicitJoins(
|
private void consumeReusablePaths(
|
||||||
SqmPath<?> sqmPath,
|
SqmPath<?> sqmPath,
|
||||||
TableGroup tableGroup,
|
TableGroup parentTableGroup,
|
||||||
Consumer<SqmPath<?>> implicitJoinChecker) {
|
Consumer<SqmPath<?>> implicitJoinChecker) {
|
||||||
if ( log.isTraceEnabled() ) {
|
if ( log.isTraceEnabled() ) {
|
||||||
log.tracef( "Visiting implicit joins for `%s`", sqmPath.getNavigablePath() );
|
log.tracef( "Visiting implicit joins for `%s`", sqmPath.getNavigablePath() );
|
||||||
}
|
}
|
||||||
|
|
||||||
sqmPath.visitImplicitJoinPaths(
|
sqmPath.visitReusablePaths(
|
||||||
joinedPath -> {
|
joinedPath -> {
|
||||||
if ( log.isTraceEnabled() ) {
|
if ( log.isTraceEnabled() ) {
|
||||||
log.tracef( "Starting implicit join handling for `%s`", joinedPath.getNavigablePath() );
|
log.tracef( "Starting implicit join handling for `%s`", joinedPath.getNavigablePath() );
|
||||||
}
|
}
|
||||||
|
// No need to create a table group for this path if no sub-paths exist
|
||||||
|
if ( joinedPath.getReusablePaths().isEmpty() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
implicitJoinChecker.accept( joinedPath );
|
final SqmPath<?> lhsPath = joinedPath.getLhs();
|
||||||
|
|
||||||
final FromClauseIndex fromClauseIndex = getFromClauseIndex();
|
final FromClauseIndex fromClauseIndex = getFromClauseIndex();
|
||||||
assert fromClauseIndex.findTableGroup( joinedPath.getLhs().getNavigablePath() ) == tableGroup;
|
final ModelPart subPart = parentTableGroup.getModelPart().findSubPart(
|
||||||
|
|
||||||
final ModelPart subPart = tableGroup.getModelPart().findSubPart(
|
|
||||||
joinedPath.getReferencedPathSource().getPathName(),
|
joinedPath.getReferencedPathSource().getPathName(),
|
||||||
sqmPath instanceof SqmTreatedPath
|
lhsPath instanceof SqmTreatedPath
|
||||||
? resolveEntityPersister( ( (SqmTreatedPath) sqmPath ).getTreatTarget() )
|
? resolveEntityPersister( ( (SqmTreatedPath<?, ?>) lhsPath ).getTreatTarget() )
|
||||||
: null
|
: null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final TableGroup tableGroup;
|
||||||
if ( subPart instanceof TableGroupJoinProducer ) {
|
if ( subPart instanceof TableGroupJoinProducer ) {
|
||||||
|
implicitJoinChecker.accept( joinedPath );
|
||||||
final TableGroupJoinProducer joinProducer = (TableGroupJoinProducer) subPart;
|
final TableGroupJoinProducer joinProducer = (TableGroupJoinProducer) subPart;
|
||||||
final TableGroupJoin tableGroupJoin = joinProducer.createTableGroupJoin(
|
final TableGroupJoin tableGroupJoin = joinProducer.createTableGroupJoin(
|
||||||
joinedPath.getNavigablePath(),
|
joinedPath.getNavigablePath(),
|
||||||
tableGroup,
|
parentTableGroup,
|
||||||
null,
|
null,
|
||||||
tableGroup.isInnerJoinPossible() ? SqlAstJoinType.INNER : SqlAstJoinType.LEFT,
|
parentTableGroup.isInnerJoinPossible() ? SqlAstJoinType.INNER : SqlAstJoinType.LEFT,
|
||||||
|
false,
|
||||||
null,
|
null,
|
||||||
this
|
this
|
||||||
);
|
);
|
||||||
|
|
||||||
fromClauseIndex.register( joinedPath, tableGroupJoin.getJoinedGroup() );
|
fromClauseIndex.register( joinedPath, tableGroupJoin.getJoinedGroup() );
|
||||||
|
tableGroup = tableGroupJoin.getJoinedGroup();
|
||||||
consumeImplicitJoins( joinedPath, tableGroupJoin.getJoinedGroup(), implicitJoinChecker );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fromClauseIndex.register( joinedPath, tableGroup );
|
tableGroup = null;
|
||||||
}
|
}
|
||||||
|
consumeReusablePaths( joinedPath, tableGroup, implicitJoinChecker );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2555,7 +2554,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
if ( sqmParameter.getAnticipatedType() == null ) {
|
if ( sqmParameter.getAnticipatedType() == null ) {
|
||||||
// this should indicate the condition that the user query did not define an
|
// this should indicate the condition that the user query did not define an
|
||||||
// explicit type in regard to this parameter. Here we should prefer the
|
// explicit type in regard to this parameter. Here we should prefer the
|
||||||
// inferable type and fallback to the binding type
|
// inferrable type and fallback to the binding type
|
||||||
final Supplier<MappingModelExpressable> currentExpressableSupplier = inferrableTypeAccessStack.getCurrent();
|
final Supplier<MappingModelExpressable> currentExpressableSupplier = inferrableTypeAccessStack.getCurrent();
|
||||||
if ( currentExpressableSupplier != null ) {
|
if ( currentExpressableSupplier != null ) {
|
||||||
final MappingModelExpressable inferredMapping = currentExpressableSupplier.get();
|
final MappingModelExpressable inferredMapping = currentExpressableSupplier.get();
|
||||||
|
@ -2697,6 +2696,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
parentTableGroup,
|
parentTableGroup,
|
||||||
null,
|
null,
|
||||||
SqlAstJoinType.INNER,
|
SqlAstJoinType.INNER,
|
||||||
|
false,
|
||||||
LockMode.READ,
|
LockMode.READ,
|
||||||
sqlAliasBaseManager,
|
sqlAliasBaseManager,
|
||||||
getSqlExpressionResolver(),
|
getSqlExpressionResolver(),
|
||||||
|
@ -3907,12 +3907,12 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
? mappingModelExpressable.getIndexDescriptor()
|
? mappingModelExpressable.getIndexDescriptor()
|
||||||
: mappingModelExpressable.getElementDescriptor();
|
: mappingModelExpressable.getElementDescriptor();
|
||||||
final List<SqlAstNode> arguments = new ArrayList<>( 1 );
|
final List<SqlAstNode> arguments = new ArrayList<>( 1 );
|
||||||
|
final NavigablePath navigablePath = pluralPartPath.getNavigablePath();
|
||||||
collectionPart.forEachSelectable(
|
collectionPart.forEachSelectable(
|
||||||
(selectionIndex, selectionMapping) -> {
|
(selectionIndex, selectionMapping) -> {
|
||||||
arguments.add(
|
arguments.add(
|
||||||
new ColumnReference(
|
new ColumnReference(
|
||||||
tableGroup.getTableReference( selectionMapping.getContainingTableExpression() ),
|
tableGroup.getTableReference( navigablePath, selectionMapping.getContainingTableExpression() ),
|
||||||
selectionMapping,
|
selectionMapping,
|
||||||
creationContext.getSessionFactory()
|
creationContext.getSessionFactory()
|
||||||
)
|
)
|
||||||
|
@ -4150,6 +4150,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
tableGroup,
|
tableGroup,
|
||||||
sqmPluralPath.getExplicitAlias(),
|
sqmPluralPath.getExplicitAlias(),
|
||||||
SqlAstJoinType.INNER,
|
SqlAstJoinType.INNER,
|
||||||
|
false,
|
||||||
LockMode.NONE,
|
LockMode.NONE,
|
||||||
sqlAliasBaseManager,
|
sqlAliasBaseManager,
|
||||||
subQueryState,
|
subQueryState,
|
||||||
|
@ -4451,7 +4452,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
final List<String> bagRoles = new ArrayList<>();
|
final List<String> bagRoles = new ArrayList<>();
|
||||||
|
|
||||||
final BiConsumer<Fetchable, Boolean> fetchableBiConsumer = (fetchable, isKeyFetchable) -> {
|
final BiConsumer<Fetchable, Boolean> fetchableBiConsumer = (fetchable, isKeyFetchable) -> {
|
||||||
final NavigablePath fetchablePath = fetchParent.getNavigablePath().append( fetchable.getFetchableName() );
|
final NavigablePath fetchablePath = fetchParent.resolveNavigablePath( fetchable );
|
||||||
|
|
||||||
final Fetch biDirectionalFetch = fetchable.resolveCircularFetch(
|
final Fetch biDirectionalFetch = fetchable.resolveCircularFetch(
|
||||||
fetchablePath,
|
fetchablePath,
|
||||||
|
@ -4594,6 +4595,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
lhs,
|
lhs,
|
||||||
alias,
|
alias,
|
||||||
SqlAstJoinType.LEFT,
|
SqlAstJoinType.LEFT,
|
||||||
|
true,
|
||||||
LockMode.NONE,
|
LockMode.NONE,
|
||||||
this
|
this
|
||||||
);
|
);
|
||||||
|
|
|
@ -46,7 +46,10 @@ public class BasicValuedPathInterpretation<T> extends AbstractSqmPathInterpretat
|
||||||
throw new SemanticException( "`" + sqmPath.getNavigablePath().getFullPath() + "` did not reference a known model part" );
|
throw new SemanticException( "`" + sqmPath.getNavigablePath().getFullPath() + "` did not reference a known model part" );
|
||||||
}
|
}
|
||||||
|
|
||||||
final TableReference tableReference = tableGroup.resolveTableReference( mapping.getContainingTableExpression() );
|
final TableReference tableReference = tableGroup.resolveTableReference(
|
||||||
|
sqmPath.getNavigablePath(),
|
||||||
|
mapping.getContainingTableExpression()
|
||||||
|
);
|
||||||
|
|
||||||
final Expression expression = sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(
|
final Expression expression = sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(
|
||||||
SqlExpressionResolver.createColumnReferenceKey(
|
SqlExpressionResolver.createColumnReferenceKey(
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class DiscriminatedAssociationPathInterpretation<T> extends AbstractSqmPa
|
||||||
|
|
||||||
mapping.forEachSelectable(
|
mapping.forEachSelectable(
|
||||||
(selectionIndex, selectableMapping) -> {
|
(selectionIndex, selectableMapping) -> {
|
||||||
final TableReference tableReference = tableGroup.resolveTableReference( selectableMapping.getContainingTableExpression() );
|
final TableReference tableReference = tableGroup.resolveTableReference( sqmPath.getNavigablePath(), selectableMapping.getContainingTableExpression() );
|
||||||
final Expression expression = converter.getSqlExpressionResolver().resolveSqlExpression(
|
final Expression expression = converter.getSqlExpressionResolver().resolveSqlExpression(
|
||||||
SqlExpressionResolver.createColumnReferenceKey( tableReference, selectableMapping.getSelectionExpression() ),
|
SqlExpressionResolver.createColumnReferenceKey( tableReference, selectableMapping.getSelectionExpression() ),
|
||||||
processingState -> new ColumnReference(
|
processingState -> new ColumnReference(
|
||||||
|
|
|
@ -61,7 +61,10 @@ public class EntityValuedPathInterpretation<T> extends AbstractSqmPathInterpreta
|
||||||
if ( mapping instanceof EntityAssociationMapping ) {
|
if ( mapping instanceof EntityAssociationMapping ) {
|
||||||
final EntityAssociationMapping associationMapping = (EntityAssociationMapping) mapping;
|
final EntityAssociationMapping associationMapping = (EntityAssociationMapping) mapping;
|
||||||
final ForeignKeyDescriptor keyDescriptor = associationMapping.getForeignKeyDescriptor();
|
final ForeignKeyDescriptor keyDescriptor = associationMapping.getForeignKeyDescriptor();
|
||||||
final TableReference tableReference = tableGroup.resolveTableReference( keyDescriptor.getKeyTable() );
|
final TableReference tableReference = tableGroup.resolveTableReference(
|
||||||
|
sqmPath.getNavigablePath(),
|
||||||
|
keyDescriptor.getKeyTable()
|
||||||
|
);
|
||||||
|
|
||||||
if ( keyDescriptor instanceof SimpleForeignKeyDescriptor ) {
|
if ( keyDescriptor instanceof SimpleForeignKeyDescriptor ) {
|
||||||
final SimpleForeignKeyDescriptor simpleKeyDescriptor = (SimpleForeignKeyDescriptor) keyDescriptor;
|
final SimpleForeignKeyDescriptor simpleKeyDescriptor = (SimpleForeignKeyDescriptor) keyDescriptor;
|
||||||
|
@ -98,7 +101,10 @@ public class EntityValuedPathInterpretation<T> extends AbstractSqmPathInterpreta
|
||||||
if ( identifierMapping instanceof BasicEntityIdentifierMapping ) {
|
if ( identifierMapping instanceof BasicEntityIdentifierMapping ) {
|
||||||
final BasicEntityIdentifierMapping simpleIdMapping = (BasicEntityIdentifierMapping) identifierMapping;
|
final BasicEntityIdentifierMapping simpleIdMapping = (BasicEntityIdentifierMapping) identifierMapping;
|
||||||
|
|
||||||
final TableReference tableReference = tableGroup.resolveTableReference( simpleIdMapping.getContainingTableExpression() );
|
final TableReference tableReference = tableGroup.resolveTableReference(
|
||||||
|
sqmPath.getNavigablePath(),
|
||||||
|
simpleIdMapping.getContainingTableExpression()
|
||||||
|
);
|
||||||
assert tableReference != null : "Could not resolve table-group : " + simpleIdMapping.getContainingTableExpression();
|
assert tableReference != null : "Could not resolve table-group : " + simpleIdMapping.getContainingTableExpression();
|
||||||
|
|
||||||
sqlExpression = sqlExprResolver.resolveSqlExpression(
|
sqlExpression = sqlExprResolver.resolveSqlExpression(
|
||||||
|
@ -189,6 +195,7 @@ public class EntityValuedPathInterpretation<T> extends AbstractSqmPathInterpreta
|
||||||
parentTableGroup,
|
parentTableGroup,
|
||||||
null,
|
null,
|
||||||
SqlAstJoinType.INNER,
|
SqlAstJoinType.INNER,
|
||||||
|
false,
|
||||||
LockMode.READ,
|
LockMode.READ,
|
||||||
sqlAstCreationState
|
sqlAstCreationState
|
||||||
);
|
);
|
||||||
|
|
|
@ -121,7 +121,7 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
|
||||||
throw UnknownPathException.unknownSubPath( this, name );
|
throw UnknownPathException.unknownSubPath( this, name );
|
||||||
}
|
}
|
||||||
|
|
||||||
return subSource.createSqmPath( this, creationState );
|
return subSource.createSqmPath( this );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import javax.persistence.metamodel.MapAttribute;
|
import javax.persistence.metamodel.MapAttribute;
|
||||||
import javax.persistence.metamodel.PluralAttribute;
|
import javax.persistence.metamodel.PluralAttribute;
|
||||||
|
@ -21,11 +19,8 @@ import javax.persistence.metamodel.SingularAttribute;
|
||||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||||
import org.hibernate.metamodel.model.domain.DomainType;
|
import org.hibernate.metamodel.model.domain.DomainType;
|
||||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||||
import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
|
import org.hibernate.metamodel.model.domain.PersistentAttribute;
|
||||||
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
|
|
||||||
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
|
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
|
||||||
import org.hibernate.query.sqm.IllegalPathUsageException;
|
import org.hibernate.query.sqm.IllegalPathUsageException;
|
||||||
import org.hibernate.query.sqm.NodeBuilder;
|
import org.hibernate.query.sqm.NodeBuilder;
|
||||||
import org.hibernate.query.sqm.SqmPathSource;
|
import org.hibernate.query.sqm.SqmPathSource;
|
||||||
|
@ -39,23 +34,14 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implements SqmPath<T> {
|
public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implements SqmPath<T> {
|
||||||
private final NavigablePath navigablePath;
|
private final NavigablePath navigablePath;
|
||||||
private final SqmPath lhs;
|
private final SqmPath<?> lhs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note that this field is only really used to support Criteria building.
|
* For HQL and Criteria processing - used to track reusable paths relative to this path.
|
||||||
* For HQL processing the {@link org.hibernate.query.hql.spi.SqmPathRegistry}
|
* E.g., given `p.mate.mate` the SqmRoot identified by `p` would
|
||||||
* serves the same purpose.
|
* have a reusable path for the `p.mate` path.
|
||||||
*/
|
*/
|
||||||
private Map<String, SqmPath> attributePathRegistry;
|
private Map<String, SqmPath<?>> reusablePaths;
|
||||||
|
|
||||||
/**
|
|
||||||
* For HQL processing - used to track implicit-join paths relative to this
|
|
||||||
* path. E.g., given `p.mate.mate` the SqmRoot identified by `p` would
|
|
||||||
* have an implicit-join for the `p.mate` path. Note however that the SqmPath
|
|
||||||
* for `p.mate` would not have one for `p.mate.mate` *unless* `p.mate.mate` were
|
|
||||||
* de-referenced somewhere else in the query.
|
|
||||||
*/
|
|
||||||
private Map<String,SqmPath<?>> implicitJoinPaths;
|
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
protected AbstractSqmPath(
|
protected AbstractSqmPath(
|
||||||
|
@ -79,7 +65,7 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
protected AbstractSqmPath(SqmPathSource<T> referencedPathSource, SqmPath lhs, NodeBuilder nodeBuilder) {
|
protected AbstractSqmPath(SqmPathSource<T> referencedPathSource, SqmPath<?> lhs, NodeBuilder nodeBuilder) {
|
||||||
this(
|
this(
|
||||||
lhs == null
|
lhs == null
|
||||||
? new NavigablePath( referencedPathSource.getPathName() )
|
? new NavigablePath( referencedPathSource.getPathName() )
|
||||||
|
@ -101,43 +87,43 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<SqmPath<?>> getImplicitJoinPaths() {
|
public List<SqmPath<?>> getReusablePaths() {
|
||||||
if ( implicitJoinPaths == null ) {
|
if ( reusablePaths == null ) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ArrayList<>( implicitJoinPaths.values() );
|
return new ArrayList<>( reusablePaths.values() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitImplicitJoinPaths(Consumer<SqmPath<?>> consumer) {
|
public void visitReusablePaths(Consumer<SqmPath<?>> consumer) {
|
||||||
if ( implicitJoinPaths != null ) {
|
if ( reusablePaths != null ) {
|
||||||
implicitJoinPaths.values().forEach( consumer );
|
reusablePaths.values().forEach( consumer );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerImplicitJoinPath(SqmPath<?> path) {
|
public void registerReusablePath(SqmPath<?> path) {
|
||||||
assert path.getLhs() == this;
|
assert path.getLhs() == this;
|
||||||
|
|
||||||
if ( implicitJoinPaths == null ) {
|
if ( reusablePaths == null ) {
|
||||||
implicitJoinPaths = new HashMap<>();
|
reusablePaths = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
final String relativeName = path.getNavigablePath().getLocalName();
|
final String relativeName = path.getNavigablePath().getLocalName();
|
||||||
|
|
||||||
final SqmPath<?> previous = implicitJoinPaths.put( relativeName, path );
|
final SqmPath<?> previous = reusablePaths.put( relativeName, path );
|
||||||
if ( previous != null && previous != path ) {
|
if ( previous != null && previous != path ) {
|
||||||
throw new IllegalStateException( "Implicit-join path registration unexpectedly overrode previous registration - " + relativeName );
|
throw new IllegalStateException( "Implicit-join path registration unexpectedly overrode previous registration - " + relativeName );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPath<?> getImplicitJoinPath(String name) {
|
public SqmPath<?> getReusablePath(String name) {
|
||||||
if ( implicitJoinPaths == null ) {
|
if ( reusablePaths == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return implicitJoinPaths.get( name );
|
return reusablePaths.get( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -185,7 +171,7 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPath createSqmPath(SqmPath lhs, SqmCreationState creationState) {
|
public SqmPath createSqmPath(SqmPath lhs) {
|
||||||
return new SqmBasicValuedSimplePath( discriminatorNavigablePath, this, AbstractSqmPath.this, nodeBuilder() );
|
return new SqmBasicValuedSimplePath( discriminatorNavigablePath, this, AbstractSqmPath.this, nodeBuilder() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +181,7 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class getBindableJavaType() {
|
public Class<?> getBindableJavaType() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,111 +220,49 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
|
||||||
throw new IllegalStateException( "Cannot resolve path `" + attributeName + "` relative to a basic-valued path: `" + getNavigablePath() + "`" );
|
throw new IllegalStateException( "Cannot resolve path `" + attributeName + "` relative to a basic-valued path: `" + getNavigablePath() + "`" );
|
||||||
}
|
}
|
||||||
|
|
||||||
return resolvePath(
|
final SqmPathSource<?> subNavigable = getReferencedPathSource().findSubPathSource( attributeName );
|
||||||
attributeName,
|
|
||||||
(pathSource, name) -> {
|
|
||||||
final SqmPathSource<?> subNavigable = getReferencedPathSource().findSubPathSource( attributeName );
|
|
||||||
|
|
||||||
if ( subNavigable == null ) {
|
if ( subNavigable == null ) {
|
||||||
throw new IllegalArgumentException( "Could not resolve attribute named `" + attributeName + "` relative to `" + getNavigablePath() + "`" );
|
throw new IllegalArgumentException( "Could not resolve attribute named `" + attributeName + "` relative to `" + getNavigablePath() + "`" );
|
||||||
}
|
|
||||||
|
|
||||||
if ( subNavigable instanceof SingularPersistentAttribute ) {
|
|
||||||
return createSingularPath( (SingularPersistentAttribute<?,?>) subNavigable );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert subNavigable instanceof PluralPersistentAttribute;
|
|
||||||
return createPluralPath( (PluralPersistentAttribute<?,?,?>) subNavigable );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private SqmPath createSingularPath(SingularPersistentAttribute attribute) {
|
|
||||||
final NavigablePath subNavPath = getNavigablePath().append( attribute.getPathName() );
|
|
||||||
|
|
||||||
switch ( attribute.getAttributeClassification() ) {
|
|
||||||
case BASIC: {
|
|
||||||
return new SqmBasicValuedSimplePath( subNavPath, attribute, this, nodeBuilder() );
|
|
||||||
}
|
|
||||||
case EMBEDDED: {
|
|
||||||
return new SqmEmbeddedValuedSimplePath( subNavPath, attribute, this, nodeBuilder() );
|
|
||||||
}
|
|
||||||
case ANY: {
|
|
||||||
return new SqmAnyValuedSimplePath( subNavPath, attribute, this, nodeBuilder() );
|
|
||||||
}
|
|
||||||
case ONE_TO_ONE:
|
|
||||||
case MANY_TO_ONE: {
|
|
||||||
return new SqmEntityValuedSimplePath( subNavPath, attribute, this, nodeBuilder() );
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
throw new UnsupportedOperationException(
|
|
||||||
String.format(
|
|
||||||
Locale.ROOT,
|
|
||||||
"Cannot create SqmPath from singular attribute [%s#%s] - unknown classification : %s",
|
|
||||||
attribute.getDeclaringType().getTypeName(),
|
|
||||||
attribute.getName(),
|
|
||||||
attribute.getAttributeClassification()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return resolvePath( attributeName, subNavigable );
|
||||||
}
|
}
|
||||||
|
|
||||||
private SqmPath createPluralPath(PluralPersistentAttribute pluralAttribute) {
|
private SqmPath<?> resolvePath(PersistentAttribute<?, ?> attribute) {
|
||||||
return new SqmPluralValuedSimplePath(
|
return resolvePath( attribute.getName(), (SqmPathSource<?>) attribute );
|
||||||
getNavigablePath().append( pluralAttribute.getPathName() ),
|
|
||||||
pluralAttribute,
|
|
||||||
this,
|
|
||||||
nodeBuilder()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SqmPath<?> resolvePath(String attributeName, SqmPathSource<?> pathSource) {
|
||||||
private SqmPath resolvePath(String attributeName, BiFunction<SqmPath, String, SqmPath> creator) {
|
if ( reusablePaths == null ) {
|
||||||
final SqmPath pathSource = getLhs();
|
reusablePaths = new HashMap<>();
|
||||||
|
final SqmPath<?> path = pathSource.createSqmPath( this );
|
||||||
if ( attributePathRegistry == null ) {
|
reusablePaths.put( attributeName, path );
|
||||||
attributePathRegistry = new HashMap<>();
|
|
||||||
final SqmPath path = creator.apply( pathSource, attributeName );
|
|
||||||
attributePathRegistry.put( attributeName, path );
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return attributePathRegistry.computeIfAbsent(
|
return reusablePaths.computeIfAbsent(
|
||||||
attributeName,
|
attributeName,
|
||||||
name -> creator.apply( pathSource, attributeName )
|
name -> pathSource.createSqmPath( this )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public SqmPath get(SingularAttribute jpaAttribute) {
|
public <Y> SqmPath<Y> get(SingularAttribute<? super T, Y> jpaAttribute) {
|
||||||
final SingularPersistentAttribute attribute = (SingularPersistentAttribute) jpaAttribute;
|
return (SqmPath<Y>) resolvePath( (PersistentAttribute<?, ?>) jpaAttribute );
|
||||||
return resolvePath(
|
|
||||||
attribute.getName(),
|
|
||||||
(pathSource, name) -> createSingularPath( attribute )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public SqmPath get(PluralAttribute attribute) {
|
public <E, C extends java.util.Collection<E>> SqmPath<C> get(PluralAttribute<T, C, E> attribute) {
|
||||||
return resolvePath(
|
return (SqmPath<C>) resolvePath( (PersistentAttribute<?, ?>) attribute );
|
||||||
attribute.getName(),
|
|
||||||
(pathSource, name) -> createPluralPath( (PluralPersistentAttribute) attribute )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public SqmPath get(MapAttribute map) {
|
public <K, V, M extends java.util.Map<K, V>> SqmPath<M> get(MapAttribute<T, K, V> map) {
|
||||||
return resolvePath(
|
return (SqmPath<M>) resolvePath( (PersistentAttribute<?, ?>) map );
|
||||||
map.getName(),
|
|
||||||
(pathSource, name) -> createPluralPath( (MapPersistentAttribute) map )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class NonAggregatedCompositeSimplePath<T> extends SqmEntityValuedSimplePa
|
||||||
throw UnknownPathException.unknownSubPath( this, name );
|
throw UnknownPathException.unknownSubPath( this, name );
|
||||||
}
|
}
|
||||||
|
|
||||||
return subPathSource.createSqmPath( this, creationState );
|
return subPathSource.createSqmPath( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -25,7 +25,7 @@ public class SqmAnyValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
|
||||||
public SqmAnyValuedSimplePath(
|
public SqmAnyValuedSimplePath(
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
SqmPathSource<T> referencedPathSource,
|
SqmPathSource<T> referencedPathSource,
|
||||||
SqmPath lhs,
|
SqmPath<?> lhs,
|
||||||
NodeBuilder nodeBuilder) {
|
NodeBuilder nodeBuilder) {
|
||||||
super( navigablePath, referencedPathSource, lhs, nodeBuilder );
|
super( navigablePath, referencedPathSource, lhs, nodeBuilder );
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ public class SqmAnyValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
|
||||||
public SqmAnyValuedSimplePath(
|
public SqmAnyValuedSimplePath(
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
SqmPathSource<T> referencedPathSource,
|
SqmPathSource<T> referencedPathSource,
|
||||||
SqmPath lhs,
|
SqmPath<?> lhs,
|
||||||
String explicitAlias,
|
String explicitAlias,
|
||||||
NodeBuilder nodeBuilder) {
|
NodeBuilder nodeBuilder) {
|
||||||
super( navigablePath, referencedPathSource, lhs, explicitAlias, nodeBuilder );
|
super( navigablePath, referencedPathSource, lhs, explicitAlias, nodeBuilder );
|
||||||
|
@ -64,7 +64,7 @@ public class SqmAnyValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
|
||||||
throw UnknownPathException.unknownSubPath( this, name );
|
throw UnknownPathException.unknownSubPath( this, name );
|
||||||
}
|
}
|
||||||
|
|
||||||
return subPathSource.createSqmPath( this, creationState );
|
return subPathSource.createSqmPath( this );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.query.sqm.tree.domain;
|
package org.hibernate.query.sqm.tree.domain;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.model.domain.AllowableParameterType;
|
||||||
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
||||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
|
@ -16,11 +17,12 @@ import org.hibernate.query.sqm.SqmPathSource;
|
||||||
import org.hibernate.query.sqm.UnknownPathException;
|
import org.hibernate.query.sqm.UnknownPathException;
|
||||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
import org.hibernate.query.hql.spi.SqmCreationState;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class SqmEmbeddedValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
|
public class SqmEmbeddedValuedSimplePath<T> extends AbstractSqmSimplePath<T> implements AllowableParameterType<T> {
|
||||||
public SqmEmbeddedValuedSimplePath(
|
public SqmEmbeddedValuedSimplePath(
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
SqmPathSource<T> referencedPathSource,
|
SqmPathSource<T> referencedPathSource,
|
||||||
|
@ -53,7 +55,7 @@ public class SqmEmbeddedValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
|
||||||
throw UnknownPathException.unknownSubPath( this, name );
|
throw UnknownPathException.unknownSubPath( this, name );
|
||||||
}
|
}
|
||||||
|
|
||||||
return subPathSource.createSqmPath( this, creationState );
|
return subPathSource.createSqmPath( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -72,7 +74,22 @@ public class SqmEmbeddedValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
|
||||||
throw new PathException( "Embeddable paths cannot be TREAT-ed" );
|
throw new PathException( "Embeddable paths cannot be TREAT-ed" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
@Override
|
||||||
|
public JavaTypeDescriptor<T> getExpressableJavaTypeDescriptor() {
|
||||||
|
return getJavaTypeDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PersistenceType getPersistenceType() {
|
||||||
|
return PersistenceType.EMBEDDABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<T> getJavaType() {
|
||||||
|
return getJavaTypeDescriptor().getJavaTypeClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
// public DomainResult createDomainResult(
|
// public DomainResult createDomainResult(
|
||||||
// String resultVariable,
|
// String resultVariable,
|
||||||
// DomainResultCreationState creationState,
|
// DomainResultCreationState creationState,
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class SqmEntityValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
|
||||||
.findPath( getLhs().getNavigablePath() ) != null;
|
.findPath( getLhs().getNavigablePath() ) != null;
|
||||||
|
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return subPathSource.createSqmPath( this, creationState );
|
return subPathSource.createSqmPath( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class SqmIndexedCollectionAccessPath<T> extends AbstractSqmPath<T> implem
|
||||||
SqmCreationState creationState) {
|
SqmCreationState creationState) {
|
||||||
final SqmPathSource subPathSource = getReferencedPathSource().getElementPathSource().findSubPathSource( name );
|
final SqmPathSource subPathSource = getReferencedPathSource().getElementPathSource().findSubPathSource( name );
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return subPathSource.createSqmPath( this, creationState );
|
return subPathSource.createSqmPath( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class SqmMaxElementPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
|
||||||
SqmCreationState creationState) {
|
SqmCreationState creationState) {
|
||||||
if ( getPluralAttribute().getElementPathSource().getSqmPathType() instanceof ManagedDomainType ) {
|
if ( getPluralAttribute().getElementPathSource().getSqmPathType() instanceof ManagedDomainType ) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return getPluralAttribute().getElementPathSource().createSqmPath( this, creationState );
|
return getPluralAttribute().getElementPathSource().createSqmPath( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new SemanticException( "Collection element cannot be de-referenced : " + getPluralDomainPath().getNavigablePath() );
|
throw new SemanticException( "Collection element cannot be de-referenced : " + getPluralDomainPath().getNavigablePath() );
|
||||||
|
|
|
@ -48,7 +48,7 @@ public class SqmMaxIndexPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
|
||||||
String name,
|
String name,
|
||||||
boolean isTerminal,
|
boolean isTerminal,
|
||||||
SqmCreationState creationState) {
|
SqmCreationState creationState) {
|
||||||
return indexPathSource.createSqmPath( this, creationState );
|
return indexPathSource.createSqmPath( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class SqmMinElementPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
|
||||||
SqmCreationState creationState) {
|
SqmCreationState creationState) {
|
||||||
if ( getPluralAttribute().getElementPathSource().getSqmPathType() instanceof ManagedDomainType ) {
|
if ( getPluralAttribute().getElementPathSource().getSqmPathType() instanceof ManagedDomainType ) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return getPluralAttribute().getElementPathSource().createSqmPath( this, creationState );
|
return getPluralAttribute().getElementPathSource().createSqmPath( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new SemanticException( "Collection element cannot be de-referenced : " + getPluralDomainPath().getNavigablePath() );
|
throw new SemanticException( "Collection element cannot be de-referenced : " + getPluralDomainPath().getNavigablePath() );
|
||||||
|
|
|
@ -48,7 +48,7 @@ public class SqmMinIndexPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
|
||||||
String name,
|
String name,
|
||||||
boolean isTerminal,
|
boolean isTerminal,
|
||||||
SqmCreationState creationState) {
|
SqmCreationState creationState) {
|
||||||
return indexPathSource.createSqmPath( this, creationState );
|
return indexPathSource.createSqmPath( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -63,21 +63,21 @@ public interface SqmPath<T> extends SqmExpression<T>, SemanticPathPart, JpaPath<
|
||||||
SqmPath<?> getLhs();
|
SqmPath<?> getLhs();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an immutable List of implicit-join paths
|
* Returns an immutable List of reusable paths
|
||||||
*/
|
*/
|
||||||
List<SqmPath<?>> getImplicitJoinPaths();
|
List<SqmPath<?>> getReusablePaths();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visit each implicit-join path relative to this path
|
* Visit each reusable path relative to this path
|
||||||
*/
|
*/
|
||||||
void visitImplicitJoinPaths(Consumer<SqmPath<?>> consumer);
|
void visitReusablePaths(Consumer<SqmPath<?>> consumer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register an implicit-join path relative to this path
|
* Register a reusable path relative to this path
|
||||||
*/
|
*/
|
||||||
void registerImplicitJoinPath(SqmPath<?> path);
|
void registerReusablePath(SqmPath<?> path);
|
||||||
|
|
||||||
SqmPath<?> getImplicitJoinPath(String name);
|
SqmPath<?> getReusablePath(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This node's type is its "referenced path source"
|
* This node's type is its "referenced path source"
|
||||||
|
|
|
@ -86,26 +86,24 @@ public class SqmPluralValuedSimplePath<E> extends AbstractSqmSimplePath<E> {
|
||||||
|
|
||||||
if ( CollectionPropertyNames.COLLECTION_ELEMENTS.equals( name ) ) {
|
if ( CollectionPropertyNames.COLLECTION_ELEMENTS.equals( name ) ) {
|
||||||
return referencedPathSource.getElementPathSource().createSqmPath(
|
return referencedPathSource.getElementPathSource().createSqmPath(
|
||||||
this,
|
this
|
||||||
creationState
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( CollectionPropertyNames.COLLECTION_INDEX.equals( name )
|
if ( CollectionPropertyNames.COLLECTION_INDEX.equals( name )
|
||||||
|| CollectionPropertyNames.COLLECTION_INDICES.equals( name ) ) {
|
|| CollectionPropertyNames.COLLECTION_INDICES.equals( name ) ) {
|
||||||
if ( referencedPathSource instanceof MapPersistentAttribute ) {
|
if ( referencedPathSource instanceof MapPersistentAttribute ) {
|
||||||
return ( (MapPersistentAttribute) referencedPathSource ).getKeyPathSource().createSqmPath( this, creationState );
|
return ( (MapPersistentAttribute) referencedPathSource ).getKeyPathSource().createSqmPath( this );
|
||||||
}
|
}
|
||||||
else if ( referencedPathSource instanceof ListPersistentAttribute ) {
|
else if ( referencedPathSource instanceof ListPersistentAttribute ) {
|
||||||
return referencedPathSource.getIndexPathSource().createSqmPath( this, creationState );
|
return referencedPathSource.getIndexPathSource().createSqmPath( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new UnsupportedOperationException( );
|
throw new UnsupportedOperationException( );
|
||||||
}
|
}
|
||||||
|
|
||||||
return referencedPathSource.getElementPathSource().createSqmPath(
|
return referencedPathSource.getElementPathSource().createSqmPath(
|
||||||
this,
|
this
|
||||||
creationState
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -33,7 +33,6 @@ import org.hibernate.metamodel.model.domain.PersistentAttribute;
|
||||||
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
|
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
|
||||||
import org.hibernate.metamodel.model.domain.SimpleDomainType;
|
import org.hibernate.metamodel.model.domain.SimpleDomainType;
|
||||||
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
|
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
|
||||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
|
||||||
import org.hibernate.query.sqm.SqmPathSource;
|
import org.hibernate.query.sqm.SqmPathSource;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
|
||||||
|
@ -374,7 +373,7 @@ public class SqmPolymorphicRootDescriptor<T> implements EntityDomainType<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPath<T> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
|
public SqmPath<T> createSqmPath(SqmPath<?> lhs) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.hibernate.sql.ast.tree.SqlAstTreeLogger;
|
||||||
import org.hibernate.sql.ast.tree.Statement;
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
import org.hibernate.sql.ast.tree.delete.DeleteStatement;
|
import org.hibernate.sql.ast.tree.delete.DeleteStatement;
|
||||||
import org.hibernate.sql.ast.tree.from.FromClause;
|
import org.hibernate.sql.ast.tree.from.FromClause;
|
||||||
|
import org.hibernate.sql.ast.tree.from.LazyTableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||||
import org.hibernate.sql.ast.tree.from.TableReferenceJoin;
|
import org.hibernate.sql.ast.tree.from.TableReferenceJoin;
|
||||||
|
@ -106,6 +107,13 @@ public class SqlTreePrinter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logTableGroupDetails(TableGroup tableGroup) {
|
private void logTableGroupDetails(TableGroup tableGroup) {
|
||||||
|
if (tableGroup instanceof LazyTableGroup ) {
|
||||||
|
TableGroup underlyingTableGroup = ( (LazyTableGroup) tableGroup ).getUnderlyingTableGroup();
|
||||||
|
if ( underlyingTableGroup != null ) {
|
||||||
|
logTableGroupDetails( underlyingTableGroup );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
logWithIndentation(
|
logWithIndentation(
|
||||||
"primaryTableReference : %s as %s",
|
"primaryTableReference : %s as %s",
|
||||||
tableGroup.getPrimaryTableReference().getTableExpression(),
|
tableGroup.getPrimaryTableReference().getTableExpression(),
|
||||||
|
|
|
@ -99,6 +99,7 @@ import org.hibernate.sql.ast.tree.expression.Summarization;
|
||||||
import org.hibernate.sql.ast.tree.expression.TrimSpecification;
|
import org.hibernate.sql.ast.tree.expression.TrimSpecification;
|
||||||
import org.hibernate.sql.ast.tree.expression.UnaryOperation;
|
import org.hibernate.sql.ast.tree.expression.UnaryOperation;
|
||||||
import org.hibernate.sql.ast.tree.from.FromClause;
|
import org.hibernate.sql.ast.tree.from.FromClause;
|
||||||
|
import org.hibernate.sql.ast.tree.from.LazyTableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||||
|
@ -2683,7 +2684,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
if ( joinedGroup instanceof VirtualTableGroup ) {
|
if ( joinedGroup instanceof VirtualTableGroup ) {
|
||||||
processTableGroupJoins( tableGroupJoin.getJoinedGroup() );
|
processTableGroupJoins( tableGroupJoin.getJoinedGroup() );
|
||||||
}
|
}
|
||||||
else {
|
else if ( !( joinedGroup instanceof LazyTableGroup ) || ( (LazyTableGroup) joinedGroup ).getUnderlyingTableGroup() != null ) {
|
||||||
appendSql( EMPTY_STRING );
|
appendSql( EMPTY_STRING );
|
||||||
SqlAstJoinType joinType = tableGroupJoin.getJoinType();
|
SqlAstJoinType joinType = tableGroupJoin.getJoinType();
|
||||||
if ( !joinedGroup.isRealTableGroup() && joinType == SqlAstJoinType.INNER && !joinedGroup.getTableReferenceJoins().isEmpty() ) {
|
if ( !joinedGroup.isRealTableGroup() && joinType == SqlAstJoinType.INNER && !joinedGroup.getTableReferenceJoins().isEmpty() ) {
|
||||||
|
|
|
@ -9,7 +9,6 @@ package org.hibernate.sql.ast.tree.cte;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.metamodel.mapping.ModelPart;
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
|
@ -62,7 +61,7 @@ public class CteTableGroup implements TableGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference getTableReference(String tableExpression) {
|
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
if ( cteTableReference.getTableExpression().equals( tableExpression ) ) {
|
if ( cteTableReference.getTableExpression().equals( tableExpression ) ) {
|
||||||
return cteTableReference;
|
return cteTableReference;
|
||||||
}
|
}
|
||||||
|
@ -70,14 +69,7 @@ public class CteTableGroup implements TableGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference resolveTableReference(String tableExpression) {
|
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
return cteTableReference;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableReference resolveTableReference(
|
|
||||||
String tableExpression,
|
|
||||||
Supplier<TableReference> creator) {
|
|
||||||
return cteTableReference;
|
return cteTableReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
package org.hibernate.sql.ast.tree.from;
|
package org.hibernate.sql.ast.tree.from;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -25,20 +25,10 @@ public abstract class AbstractColumnReferenceQualifier implements ColumnReferenc
|
||||||
// TableReference handling
|
// TableReference handling
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference resolveTableReference(String tableExpression, Supplier<TableReference> creator) {
|
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
final TableReference existing = getTableReferenceInternal( tableExpression );
|
|
||||||
if ( existing != null ) {
|
|
||||||
return existing;
|
|
||||||
}
|
|
||||||
|
|
||||||
return creator.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableReference resolveTableReference(String tableExpression) {
|
|
||||||
assert tableExpression != null;
|
assert tableExpression != null;
|
||||||
|
|
||||||
final TableReference tableReference = getTableReferenceInternal( tableExpression );
|
final TableReference tableReference = getTableReferenceInternal( navigablePath, tableExpression );
|
||||||
if ( tableReference == null ) {
|
if ( tableReference == null ) {
|
||||||
throw new IllegalStateException( "Could not resolve binding for table `" + tableExpression + "`" );
|
throw new IllegalStateException( "Could not resolve binding for table `" + tableExpression + "`" );
|
||||||
}
|
}
|
||||||
|
@ -47,18 +37,24 @@ public abstract class AbstractColumnReferenceQualifier implements ColumnReferenc
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference getTableReference(String tableExpression) {
|
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
return getTableReferenceInternal( tableExpression );
|
return getTableReferenceInternal( navigablePath, tableExpression );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TableReference getTableReferenceInternal(String tableExpression) {
|
protected TableReference getTableReferenceInternal(
|
||||||
if ( getPrimaryTableReference().getTableReference( tableExpression ) != null) {
|
NavigablePath navigablePath,
|
||||||
return getPrimaryTableReference();
|
String tableExpression) {
|
||||||
|
final TableReference primaryTableReference = getPrimaryTableReference().getTableReference( navigablePath , tableExpression );
|
||||||
|
if ( primaryTableReference != null) {
|
||||||
|
return primaryTableReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( TableReferenceJoin tableJoin : getTableReferenceJoins() ) {
|
for ( TableReferenceJoin tableJoin : getTableReferenceJoins() ) {
|
||||||
if ( tableJoin.getJoinedTableReference().getTableReference( tableExpression ) != null) {
|
final TableReference tableReference = tableJoin.getJoinedTableReference().getTableReference(
|
||||||
return tableJoin.getJoinedTableReference();
|
navigablePath,
|
||||||
|
tableExpression );
|
||||||
|
if ( tableReference != null) {
|
||||||
|
return tableReference;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,13 +6,15 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.sql.ast.tree.from;
|
package org.hibernate.sql.ast.tree.from;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
import org.hibernate.query.NavigablePath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface ColumnReferenceQualifier {
|
public interface ColumnReferenceQualifier {
|
||||||
TableReference resolveTableReference(String tableExpression, Supplier<TableReference> creator);
|
TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression);
|
||||||
TableReference resolveTableReference(String tableExpression);
|
TableReference getTableReference(NavigablePath navigablePath, String tableExpression);
|
||||||
TableReference getTableReference(String tableExpression);
|
default TableReference getTableReference(String tableExpression) {
|
||||||
|
return getTableReference( null, tableExpression );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||||
|
@ -110,26 +109,19 @@ public class CompositeTableGroup implements VirtualTableGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference getTableReference(String tableExpression) {
|
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
return underlyingTableGroup.getTableReference( tableExpression );
|
return underlyingTableGroup.getTableReference( tableExpression );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference resolveTableReference(
|
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
String tableExpression,
|
TableReference tableReference = underlyingTableGroup.getTableReference( navigablePath, tableExpression );
|
||||||
Supplier<TableReference> creator) {
|
|
||||||
return underlyingTableGroup.resolveTableReference( tableExpression, creator );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableReference resolveTableReference(String tableExpression) {
|
|
||||||
TableReference tableReference = underlyingTableGroup.getTableReference( tableExpression );
|
|
||||||
if ( tableReference != null ) {
|
if ( tableReference != null ) {
|
||||||
return tableReference;
|
return tableReference;
|
||||||
}
|
}
|
||||||
for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
|
for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
|
||||||
final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference();
|
final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference().getTableReference( navigablePath, tableExpression );
|
||||||
if ( primaryTableReference.getTableExpression().equals( tableExpression ) ) {
|
if ( primaryTableReference != null ) {
|
||||||
return primaryTableReference;
|
return primaryTableReference;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.sql.ast.SqlAstJoinType;
|
import org.hibernate.sql.ast.SqlAstJoinType;
|
||||||
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||||
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||||
|
@ -59,20 +60,23 @@ public class CorrelatedTableGroup extends AbstractTableGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TableReference getTableReferenceInternal(String tableExpression) {
|
protected TableReference getTableReferenceInternal(
|
||||||
final TableReference primaryTableReference = correlatedTableGroup.getPrimaryTableReference();
|
NavigablePath navigablePath,
|
||||||
if ( tableExpression.equals( primaryTableReference.getTableExpression() ) ) {
|
String tableExpression) {
|
||||||
|
final TableReference primaryTableReference = correlatedTableGroup.getPrimaryTableReference().getTableReference( navigablePath, tableExpression );
|
||||||
|
if ( primaryTableReference != null ) {
|
||||||
return primaryTableReference;
|
return primaryTableReference;
|
||||||
}
|
}
|
||||||
for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
|
for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
|
||||||
final TableReference groupTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference();
|
final TableReference groupTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference().getTableReference( navigablePath, tableExpression );
|
||||||
if ( groupTableReference.getTableReference( tableExpression ) != null ) {
|
if ( groupTableReference != null ) {
|
||||||
return groupTableReference;
|
return groupTableReference;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for ( TableReferenceJoin tableReferenceJoin : correlatedTableGroup.getTableReferenceJoins() ) {
|
for ( TableReferenceJoin tableReferenceJoin : correlatedTableGroup.getTableReferenceJoins() ) {
|
||||||
if ( tableExpression.equals( tableReferenceJoin.getJoinedTableReference().getTableExpression() ) ) {
|
final TableReference tableReference = tableReferenceJoin.getJoinedTableReference().getTableReference( navigablePath, tableExpression );
|
||||||
return tableReferenceJoin.getJoinedTableReference();
|
if ( tableReference != null ) {
|
||||||
|
return tableReference;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -0,0 +1,171 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.sql.ast.tree.from;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import org.hibernate.LockMode;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class LazyTableGroup extends AbstractColumnReferenceQualifier implements TableGroup {
|
||||||
|
|
||||||
|
private final NavigablePath navigablePath;
|
||||||
|
private final TableGroupProducer producer;
|
||||||
|
private final LockMode lockMode;
|
||||||
|
private final SqlAliasBase sqlAliasBase;
|
||||||
|
private final SessionFactoryImplementor sessionFactory;
|
||||||
|
private final Supplier<TableGroup> tableGroupSupplier;
|
||||||
|
private final TableGroup parentTableGroup;
|
||||||
|
private final Predicate<NavigablePath> navigablePathChecker;
|
||||||
|
private Consumer<TableGroup> tableGroupConsumer;
|
||||||
|
private TableGroup tableGroup;
|
||||||
|
|
||||||
|
public LazyTableGroup(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
Supplier<TableGroup> tableGroupSupplier,
|
||||||
|
Predicate<NavigablePath> navigablePathChecker,
|
||||||
|
TableGroupProducer tableGroupProducer,
|
||||||
|
LockMode lockMode,
|
||||||
|
SqlAliasBase sqlAliasBase,
|
||||||
|
SessionFactoryImplementor sessionFactory,
|
||||||
|
TableGroup parentTableGroup) {
|
||||||
|
this.navigablePath = navigablePath;
|
||||||
|
this.producer = tableGroupProducer;
|
||||||
|
this.lockMode = lockMode;
|
||||||
|
this.sqlAliasBase = sqlAliasBase;
|
||||||
|
this.tableGroupSupplier = tableGroupSupplier;
|
||||||
|
this.navigablePathChecker = navigablePathChecker;
|
||||||
|
this.parentTableGroup = parentTableGroup;
|
||||||
|
this.sessionFactory = sessionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TableGroup getUnderlyingTableGroup() {
|
||||||
|
return tableGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TableGroup getTableGroup() {
|
||||||
|
if ( tableGroup != null ) {
|
||||||
|
return tableGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
tableGroup = tableGroupSupplier.get();
|
||||||
|
if ( tableGroupConsumer != null ) {
|
||||||
|
tableGroupConsumer.accept( tableGroup );
|
||||||
|
}
|
||||||
|
return tableGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTableGroupInitializerCallback(Consumer<TableGroup> tableGroupConsumer) {
|
||||||
|
this.tableGroupConsumer = tableGroupConsumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyAffectedTableNames(Consumer<String> nameCollector) {
|
||||||
|
if ( tableGroup != null ) {
|
||||||
|
tableGroup.applyAffectedTableNames( nameCollector );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TableReference getPrimaryTableReference() {
|
||||||
|
return getTableGroup().getPrimaryTableReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TableReferenceJoin> getTableReferenceJoins() {
|
||||||
|
return tableGroup == null ? Collections.emptyList() : tableGroup.getTableReferenceJoins();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TableGroupJoin> getTableGroupJoins() {
|
||||||
|
return tableGroup == null ? Collections.emptyList() : tableGroup.getTableGroupJoins();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasTableGroupJoins() {
|
||||||
|
return tableGroup != null && tableGroup.hasTableGroupJoins();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTableGroupJoin(TableGroupJoin join) {
|
||||||
|
getTableGroup().addTableGroupJoin( join );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitTableGroupJoins(Consumer<TableGroupJoin> consumer) {
|
||||||
|
if ( tableGroup != null ) {
|
||||||
|
tableGroup.visitTableGroupJoins( consumer );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NavigablePath getNavigablePath() {
|
||||||
|
return navigablePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getGroupAlias() {
|
||||||
|
return sqlAliasBase.getAliasStem();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TableGroupProducer getModelPart() {
|
||||||
|
return producer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelPart getExpressionType() {
|
||||||
|
return getModelPart();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LockMode getLockMode() {
|
||||||
|
return lockMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SessionFactoryImplementor getSessionFactory() {
|
||||||
|
return sessionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInnerJoinPossible() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRealTableGroup() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TableReference getTableReferenceInternal(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
String tableExpression) {
|
||||||
|
if ( navigablePath == null || navigablePathChecker.test( navigablePath ) ) {
|
||||||
|
final TableReference reference = parentTableGroup.getTableReference(
|
||||||
|
navigablePath,
|
||||||
|
tableExpression
|
||||||
|
);
|
||||||
|
if ( reference != null ) {
|
||||||
|
return reference;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return getTableGroup().getTableReference( navigablePath, tableExpression );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,7 +9,6 @@ package org.hibernate.sql.ast.tree.from;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.metamodel.mapping.ModelPart;
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
|
@ -62,20 +61,15 @@ public class MutatingTableReferenceGroupWrapper implements VirtualTableGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference getTableReference(String tableExpression) {
|
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
return mutatingTableReference.getTableExpression().equals( tableExpression )
|
return mutatingTableReference.getTableExpression().equals( tableExpression )
|
||||||
? mutatingTableReference
|
? mutatingTableReference
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference resolveTableReference(String tableExpression, Supplier<TableReference> creator) {
|
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
return resolveTableReference( tableExpression );
|
return getTableReference( navigablePath, tableExpression );
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableReference resolveTableReference(String tableExpression) {
|
|
||||||
return getTableReference( tableExpression );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -26,6 +26,7 @@ public class StandardTableGroup extends AbstractTableGroup {
|
||||||
private final Predicate<String> tableReferenceJoinNameChecker;
|
private final Predicate<String> tableReferenceJoinNameChecker;
|
||||||
private final BiFunction<String,TableGroup,TableReferenceJoin> tableReferenceJoinCreator;
|
private final BiFunction<String,TableGroup,TableReferenceJoin> tableReferenceJoinCreator;
|
||||||
private final boolean realTableGroup;
|
private final boolean realTableGroup;
|
||||||
|
private final boolean fetched;
|
||||||
|
|
||||||
private List<TableReferenceJoin> tableJoins;
|
private List<TableReferenceJoin> tableJoins;
|
||||||
|
|
||||||
|
@ -39,6 +40,7 @@ public class StandardTableGroup extends AbstractTableGroup {
|
||||||
super( navigablePath, tableGroupProducer, lockMode, sqlAliasBase, sessionFactory );
|
super( navigablePath, tableGroupProducer, lockMode, sqlAliasBase, sessionFactory );
|
||||||
this.primaryTableReference = primaryTableReference;
|
this.primaryTableReference = primaryTableReference;
|
||||||
this.realTableGroup = false;
|
this.realTableGroup = false;
|
||||||
|
this.fetched = false;
|
||||||
this.tableJoins = Collections.emptyList();
|
this.tableJoins = Collections.emptyList();
|
||||||
this.tableReferenceJoinCreator = null;
|
this.tableReferenceJoinCreator = null;
|
||||||
this.tableReferenceJoinNameChecker = s -> {
|
this.tableReferenceJoinNameChecker = s -> {
|
||||||
|
@ -64,6 +66,27 @@ public class StandardTableGroup extends AbstractTableGroup {
|
||||||
super( navigablePath, tableGroupProducer, lockMode, sqlAliasBase, sessionFactory );
|
super( navigablePath, tableGroupProducer, lockMode, sqlAliasBase, sessionFactory );
|
||||||
this.primaryTableReference = primaryTableReference;
|
this.primaryTableReference = primaryTableReference;
|
||||||
this.realTableGroup = realTableGroup;
|
this.realTableGroup = realTableGroup;
|
||||||
|
this.fetched = false;
|
||||||
|
this.tableJoins = null;
|
||||||
|
this.tableReferenceJoinNameChecker = tableReferenceJoinNameChecker;
|
||||||
|
this.tableReferenceJoinCreator = tableReferenceJoinCreator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StandardTableGroup(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
TableGroupProducer tableGroupProducer,
|
||||||
|
boolean fetched,
|
||||||
|
LockMode lockMode,
|
||||||
|
TableReference primaryTableReference,
|
||||||
|
boolean realTableGroup,
|
||||||
|
SqlAliasBase sqlAliasBase,
|
||||||
|
Predicate<String> tableReferenceJoinNameChecker,
|
||||||
|
BiFunction<String, TableGroup, TableReferenceJoin> tableReferenceJoinCreator,
|
||||||
|
SessionFactoryImplementor sessionFactory) {
|
||||||
|
super( navigablePath, tableGroupProducer, lockMode, sqlAliasBase, sessionFactory );
|
||||||
|
this.primaryTableReference = primaryTableReference;
|
||||||
|
this.realTableGroup = realTableGroup;
|
||||||
|
this.fetched = fetched;
|
||||||
this.tableJoins = null;
|
this.tableJoins = null;
|
||||||
this.tableReferenceJoinNameChecker = tableReferenceJoinNameChecker;
|
this.tableReferenceJoinNameChecker = tableReferenceJoinNameChecker;
|
||||||
this.tableReferenceJoinCreator = tableReferenceJoinCreator;
|
this.tableReferenceJoinCreator = tableReferenceJoinCreator;
|
||||||
|
@ -78,11 +101,6 @@ public class StandardTableGroup extends AbstractTableGroup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableReference getTableReference(String tableExpression) {
|
|
||||||
return getTableReferenceInternal( tableExpression );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference getPrimaryTableReference() {
|
public TableReference getPrimaryTableReference() {
|
||||||
return primaryTableReference;
|
return primaryTableReference;
|
||||||
|
@ -98,6 +116,11 @@ public class StandardTableGroup extends AbstractTableGroup {
|
||||||
return realTableGroup;
|
return realTableGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFetched() {
|
||||||
|
return fetched;
|
||||||
|
}
|
||||||
|
|
||||||
public void addTableReferenceJoin(TableReferenceJoin join) {
|
public void addTableReferenceJoin(TableReferenceJoin join) {
|
||||||
if ( tableJoins == null ) {
|
if ( tableJoins == null ) {
|
||||||
tableJoins = new ArrayList<>();
|
tableJoins = new ArrayList<>();
|
||||||
|
@ -106,8 +129,10 @@ public class StandardTableGroup extends AbstractTableGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference getTableReferenceInternal(String tableExpression) {
|
public TableReference getTableReferenceInternal(
|
||||||
TableReference tableReference = primaryTableReference.getTableReference( tableExpression );
|
NavigablePath navigablePath,
|
||||||
|
String tableExpression) {
|
||||||
|
TableReference tableReference = primaryTableReference.getTableReference( navigablePath, tableExpression );
|
||||||
if ( tableReference != null ) {
|
if ( tableReference != null ) {
|
||||||
return tableReference;
|
return tableReference;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +143,7 @@ public class StandardTableGroup extends AbstractTableGroup {
|
||||||
final TableReferenceJoin join = tableJoins.get( i );
|
final TableReferenceJoin join = tableJoins.get( i );
|
||||||
assert join != null;
|
assert join != null;
|
||||||
final TableReference resolveTableReference = join.getJoinedTableReference()
|
final TableReference resolveTableReference = join.getJoinedTableReference()
|
||||||
.getTableReference( tableExpression );
|
.getTableReference( navigablePath, tableExpression );
|
||||||
if ( resolveTableReference != null ) {
|
if ( resolveTableReference != null ) {
|
||||||
return resolveTableReference;
|
return resolveTableReference;
|
||||||
}
|
}
|
||||||
|
@ -130,7 +155,7 @@ public class StandardTableGroup extends AbstractTableGroup {
|
||||||
|
|
||||||
for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
|
for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
|
||||||
final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference();
|
final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference();
|
||||||
if ( primaryTableReference.getTableReference( tableExpression ) != null ) {
|
if ( primaryTableReference.getTableReference( navigablePath, tableExpression ) != null ) {
|
||||||
return primaryTableReference;
|
return primaryTableReference;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,4 +91,8 @@ public interface TableGroup extends SqlAstNode, ColumnReferenceQualifier, SqmPat
|
||||||
default boolean isRealTableGroup() {
|
default boolean isRealTableGroup() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default boolean isFetched() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ public interface TableGroupJoinProducer extends TableGroupProducer {
|
||||||
TableGroup lhs,
|
TableGroup lhs,
|
||||||
String explicitSourceAlias,
|
String explicitSourceAlias,
|
||||||
SqlAstJoinType sqlAstJoinType,
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
SqlAstCreationState creationState) {
|
SqlAstCreationState creationState) {
|
||||||
return createTableGroupJoin(
|
return createTableGroupJoin(
|
||||||
|
@ -33,6 +34,7 @@ public interface TableGroupJoinProducer extends TableGroupProducer {
|
||||||
lhs,
|
lhs,
|
||||||
explicitSourceAlias,
|
explicitSourceAlias,
|
||||||
sqlAstJoinType,
|
sqlAstJoinType,
|
||||||
|
fetched,
|
||||||
lockMode,
|
lockMode,
|
||||||
creationState.getSqlAliasBaseGenerator(),
|
creationState.getSqlAliasBaseGenerator(),
|
||||||
creationState.getSqlExpressionResolver(),
|
creationState.getSqlExpressionResolver(),
|
||||||
|
@ -48,6 +50,7 @@ public interface TableGroupJoinProducer extends TableGroupProducer {
|
||||||
TableGroup lhs,
|
TableGroup lhs,
|
||||||
String explicitSourceAlias,
|
String explicitSourceAlias,
|
||||||
SqlAstJoinType sqlAstJoinType,
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
package org.hibernate.sql.ast.tree.from;
|
package org.hibernate.sql.ast.tree.from;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.sql.ast.SqlAstWalker;
|
import org.hibernate.sql.ast.SqlAstWalker;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
|
||||||
|
@ -52,12 +52,7 @@ public class TableReference implements SqlAstNode, ColumnReferenceQualifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference resolveTableReference(String tableExpression, Supplier<TableReference> creator) {
|
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
throw new UnsupportedOperationException( "Cannot create a TableReference relative to a TableReference" );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableReference resolveTableReference(String tableExpression) {
|
|
||||||
if ( tableExpression.equals( getTableExpression() ) ) {
|
if ( tableExpression.equals( getTableExpression() ) ) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +60,7 @@ public class TableReference implements SqlAstNode, ColumnReferenceQualifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference getTableReference(String tableExpression) {
|
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
if ( this.tableExpression.equals( tableExpression ) ) {
|
if ( this.tableExpression.equals( tableExpression ) ) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.metamodel.mapping.ModelPart;
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
|
@ -109,19 +108,13 @@ public class UnionTableGroup implements VirtualTableGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference getTableReference(String tableExpression) {
|
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
// assert tableReference.getTableExpression().equals( tableExpression );
|
// assert tableReference.getTableExpression().equals( tableExpression );
|
||||||
return tableReference;
|
return tableReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference resolveTableReference(String tableExpression, Supplier<TableReference> creator) {
|
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
assert tableReference.getTableExpression().equals( tableExpression );
|
|
||||||
return tableReference;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableReference resolveTableReference(String tableExpression) {
|
|
||||||
// assert tableReference.getTableExpression().equals( tableExpression );
|
// assert tableReference.getTableExpression().equals( tableExpression );
|
||||||
return tableReference;
|
return tableReference;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.sql.ast.tree.from;
|
package org.hibernate.sql.ast.tree.from;
|
||||||
|
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrea Boriero
|
* @author Andrea Boriero
|
||||||
|
@ -25,7 +26,7 @@ public class UnionTableReference extends TableReference {
|
||||||
this.subclassTableSpaceExpressions = subclassTableSpaceExpressions;
|
this.subclassTableSpaceExpressions = subclassTableSpaceExpressions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TableReference resolveTableReference(String tableExpression) {
|
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
if ( hasTableExpression( tableExpression ) ) {
|
if ( hasTableExpression( tableExpression ) ) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +34,7 @@ public class UnionTableReference extends TableReference {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference getTableReference(String tableExpression) {
|
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
if ( hasTableExpression( tableExpression ) ) {
|
if ( hasTableExpression( tableExpression ) ) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,10 @@ public interface FetchParent extends DomainResultGraphNode {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default NavigablePath resolveNavigablePath(Fetchable fetchable) {
|
||||||
|
return getNavigablePath().append( fetchable.getFetchableName() );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whereas {@link #getReferencedMappingContainer} and {@link #getReferencedMappingType} return the
|
* Whereas {@link #getReferencedMappingContainer} and {@link #getReferencedMappingType} return the
|
||||||
* referenced container type, this method returns the referenced part.
|
* referenced container type, this method returns the referenced part.
|
||||||
|
|
|
@ -8,7 +8,6 @@ package org.hibernate.sql.results.graph.collection.internal;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.metamodel.mapping.ModelPart;
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
|
@ -103,18 +102,13 @@ public class EntityCollectionPartTableGroup implements TableGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference getTableReference(String tableExpression) {
|
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
return collectionTableGroup.getTableReference( tableExpression );
|
return collectionTableGroup.getTableReference( tableExpression );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference resolveTableReference(String tableExpression, Supplier<TableReference> creator) {
|
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
|
||||||
return collectionTableGroup.resolveTableReference( tableExpression, creator );
|
return collectionTableGroup.resolveTableReference( navigablePath, tableExpression );
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableReference resolveTableReference(String tableExpression) {
|
|
||||||
return collectionTableGroup.resolveTableReference( tableExpression );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -66,6 +66,7 @@ public class EmbeddableFetchImpl extends AbstractFetchParent implements Embeddab
|
||||||
lhsTableGroup,
|
lhsTableGroup,
|
||||||
null,
|
null,
|
||||||
nullable ? SqlAstJoinType.LEFT : SqlAstJoinType.INNER,
|
nullable ? SqlAstJoinType.LEFT : SqlAstJoinType.INNER,
|
||||||
|
true,
|
||||||
LockMode.NONE,
|
LockMode.NONE,
|
||||||
creationState.getSqlAstCreationState()
|
creationState.getSqlAstCreationState()
|
||||||
);
|
);
|
||||||
|
|
|
@ -61,12 +61,22 @@ public class EmbeddableForeignKeyResultImpl<T>
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
String resultVariable,
|
String resultVariable,
|
||||||
DomainResultCreationState creationState) {
|
DomainResultCreationState creationState) {
|
||||||
|
final boolean shouldSelect;
|
||||||
|
if ( fetchable instanceof ToOneAttributeMapping ) {
|
||||||
|
// We need to make sure to-ones are always delayed to avoid cycles while resolving entity keys
|
||||||
|
final ToOneAttributeMapping toOne = (ToOneAttributeMapping) fetchable;
|
||||||
|
shouldSelect = selected && !creationState.isAssociationKeyVisited(
|
||||||
|
toOne.getForeignKeyDescriptor().getAssociationKey()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
shouldSelect = selected;
|
||||||
|
}
|
||||||
return fetchable.generateFetch(
|
return fetchable.generateFetch(
|
||||||
this,
|
this,
|
||||||
fetchablePath,
|
fetchablePath,
|
||||||
fetchTiming,
|
fetchTiming,
|
||||||
// We need to make sure to-ones are always delayed to avoid cycles while resolving entity keys
|
shouldSelect,
|
||||||
selected && !( fetchable instanceof ToOneAttributeMapping ),
|
|
||||||
lockMode,
|
lockMode,
|
||||||
resultVariable,
|
resultVariable,
|
||||||
creationState
|
creationState
|
||||||
|
|
|
@ -52,6 +52,7 @@ public class EmbeddableResultImpl<T> extends AbstractFetchParent implements Embe
|
||||||
fromClauseAccess.findTableGroup( navigablePath.getParent() ),
|
fromClauseAccess.findTableGroup( navigablePath.getParent() ),
|
||||||
resultVariable,
|
resultVariable,
|
||||||
SqlAstJoinType.INNER,
|
SqlAstJoinType.INNER,
|
||||||
|
true,
|
||||||
LockMode.NONE,
|
LockMode.NONE,
|
||||||
creationState.getSqlAstCreationState()
|
creationState.getSqlAstCreationState()
|
||||||
);
|
);
|
||||||
|
|
|
@ -73,6 +73,16 @@ public abstract class AbstractEntityResultGraphNode extends AbstractFetchParent
|
||||||
identifierResult = null;
|
identifierResult = null;
|
||||||
visitIdentifierMapping( identifierNavigablePath, creationState, identifierMapping, entityTableGroup );
|
visitIdentifierMapping( identifierNavigablePath, creationState, identifierMapping, entityTableGroup );
|
||||||
}
|
}
|
||||||
|
else if ( referencedModelPart instanceof ToOneAttributeMapping
|
||||||
|
&& ( (ToOneAttributeMapping) referencedModelPart ).canJoinForeignKey( identifierMapping ) ) {
|
||||||
|
// If we don't do this here, LazyTableGroup#getTableReferenceInternal would have to use the target table in case {id} is encountered
|
||||||
|
identifierResult = ( (ToOneAttributeMapping) referencedModelPart ).getForeignKeyDescriptor().createDomainResult(
|
||||||
|
navigablePath,
|
||||||
|
creationState.getSqlAstCreationState().getFromClauseAccess().findTableGroup( navigablePath.getParent() ),
|
||||||
|
null,
|
||||||
|
creationState
|
||||||
|
);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
identifierResult = identifierMapping.createDomainResult(
|
identifierResult = identifierMapping.createDomainResult(
|
||||||
identifierNavigablePath,
|
identifierNavigablePath,
|
||||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.sql.results.graph.entity.internal;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.engine.FetchTiming;
|
import org.hibernate.engine.FetchTiming;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.FetchParent;
|
import org.hibernate.sql.results.graph.FetchParent;
|
||||||
|
@ -29,6 +30,7 @@ public class EntityFetchJoinedImpl extends AbstractNonLazyEntityFetch {
|
||||||
public EntityFetchJoinedImpl(
|
public EntityFetchJoinedImpl(
|
||||||
FetchParent fetchParent,
|
FetchParent fetchParent,
|
||||||
EntityValuedFetchable fetchedAttribute,
|
EntityValuedFetchable fetchedAttribute,
|
||||||
|
TableGroup tableGroup,
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
boolean nullable,
|
boolean nullable,
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
|
@ -38,6 +40,7 @@ public class EntityFetchJoinedImpl extends AbstractNonLazyEntityFetch {
|
||||||
entityResult = new EntityResultImpl(
|
entityResult = new EntityResultImpl(
|
||||||
navigablePath,
|
navigablePath,
|
||||||
fetchedAttribute,
|
fetchedAttribute,
|
||||||
|
tableGroup,
|
||||||
null,
|
null,
|
||||||
creationState
|
creationState
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,9 +9,13 @@ package org.hibernate.sql.results.graph.entity.internal;
|
||||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||||
|
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
||||||
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
||||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
import org.hibernate.sql.results.graph.FetchableContainer;
|
import org.hibernate.sql.results.graph.FetchableContainer;
|
||||||
import org.hibernate.sql.results.graph.entity.AbstractEntityResultGraphNode;
|
import org.hibernate.sql.results.graph.entity.AbstractEntityResultGraphNode;
|
||||||
import org.hibernate.sql.results.graph.entity.EntityInitializer;
|
import org.hibernate.sql.results.graph.entity.EntityInitializer;
|
||||||
|
@ -24,19 +28,22 @@ import org.hibernate.sql.results.graph.entity.EntityResult;
|
||||||
*/
|
*/
|
||||||
public class EntityResultImpl extends AbstractEntityResultGraphNode implements EntityResult {
|
public class EntityResultImpl extends AbstractEntityResultGraphNode implements EntityResult {
|
||||||
|
|
||||||
|
private final TableGroup tableGroup;
|
||||||
private final String resultVariable;
|
private final String resultVariable;
|
||||||
|
|
||||||
public EntityResultImpl(
|
public EntityResultImpl(
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
EntityValuedModelPart entityValuedModelPart,
|
EntityValuedModelPart entityValuedModelPart,
|
||||||
|
TableGroup tableGroup,
|
||||||
String resultVariable,
|
String resultVariable,
|
||||||
DomainResultCreationState creationState) {
|
DomainResultCreationState creationState) {
|
||||||
this( navigablePath, entityValuedModelPart, resultVariable, null, creationState );
|
this( navigablePath, entityValuedModelPart, tableGroup, resultVariable, null, creationState );
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityResultImpl(
|
public EntityResultImpl(
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
EntityValuedModelPart entityValuedModelPart,
|
EntityValuedModelPart entityValuedModelPart,
|
||||||
|
TableGroup tableGroup,
|
||||||
String resultVariable,
|
String resultVariable,
|
||||||
EntityMappingType targetType,
|
EntityMappingType targetType,
|
||||||
DomainResultCreationState creationState) {
|
DomainResultCreationState creationState) {
|
||||||
|
@ -46,12 +53,27 @@ public class EntityResultImpl extends AbstractEntityResultGraphNode implements E
|
||||||
navigablePath,
|
navigablePath,
|
||||||
creationState
|
creationState
|
||||||
);
|
);
|
||||||
|
this.tableGroup = tableGroup;
|
||||||
this.resultVariable = resultVariable;
|
this.resultVariable = resultVariable;
|
||||||
|
|
||||||
afterInitialize( creationState );
|
afterInitialize( creationState );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NavigablePath resolveNavigablePath(Fetchable fetchable) {
|
||||||
|
// todo: this is not ideal yet as we could potentially resolve a path that we did not intend
|
||||||
|
// to fix this, we'd need to know if the table group is for a fetch
|
||||||
|
if ( fetchable instanceof TableGroupProducer &&
|
||||||
|
!getNavigablePath().getUnaliasedLocalName().equals( getNavigablePath().getLocalName() ) ) {
|
||||||
|
for ( TableGroupJoin tableGroupJoin : tableGroup.getTableGroupJoins() ) {
|
||||||
|
if ( tableGroupJoin.getJoinedGroup().isFetched() && tableGroupJoin.getJoinedGroup().getModelPart() == fetchable ) {
|
||||||
|
return tableGroupJoin.getNavigablePath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.resolveNavigablePath( fetchable );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FetchableContainer getReferencedMappingType() {
|
public FetchableContainer getReferencedMappingType() {
|
||||||
return getReferencedMappingContainer();
|
return getReferencedMappingContainer();
|
||||||
|
|
|
@ -24,9 +24,10 @@ public class EntityResultJoinedSubclassImpl extends EntityResultImpl {
|
||||||
public EntityResultJoinedSubclassImpl(
|
public EntityResultJoinedSubclassImpl(
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
EntityValuedModelPart entityValuedModelPart,
|
EntityValuedModelPart entityValuedModelPart,
|
||||||
|
TableGroup tableGroup,
|
||||||
String resultVariable,
|
String resultVariable,
|
||||||
DomainResultCreationState creationState) {
|
DomainResultCreationState creationState) {
|
||||||
super( navigablePath, entityValuedModelPart, resultVariable, creationState );
|
super( navigablePath, entityValuedModelPart, tableGroup, resultVariable, creationState );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.hibernate.type.descriptor.jdbc.RealTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.SmallIntTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.SmallIntTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.TimeTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.TimeTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.TimestampTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.TimestampTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.TimestampWithTimeZoneDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.TinyIntTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.TinyIntTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.VarbinaryTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.VarbinaryTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.VarcharTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.VarcharTypeDescriptor;
|
||||||
|
@ -57,6 +58,7 @@ public class JdbcTypeDescriptorBaseline {
|
||||||
|
|
||||||
target.addDescriptor( DateTypeDescriptor.INSTANCE );
|
target.addDescriptor( DateTypeDescriptor.INSTANCE );
|
||||||
target.addDescriptor( TimestampTypeDescriptor.INSTANCE );
|
target.addDescriptor( TimestampTypeDescriptor.INSTANCE );
|
||||||
|
target.addDescriptor( TimestampWithTimeZoneDescriptor.INSTANCE );
|
||||||
target.addDescriptor( TimeTypeDescriptor.INSTANCE );
|
target.addDescriptor( TimeTypeDescriptor.INSTANCE );
|
||||||
|
|
||||||
target.addDescriptor( BinaryTypeDescriptor.INSTANCE );
|
target.addDescriptor( BinaryTypeDescriptor.INSTANCE );
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue