Fix @manyToMany member of query
This commit is contained in:
parent
bd3775b114
commit
7e87deb349
|
@ -20,6 +20,10 @@ public class AssociationKey {
|
|||
this.columns = columns;
|
||||
}
|
||||
|
||||
public String getTable() {
|
||||
return table;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( this == o ) {
|
||||
|
|
|
@ -166,10 +166,9 @@ public class EntityCollectionPart
|
|||
TableGroup tableGroup,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
return fkTargetModelPart.createDomainResult( navigablePath, tableGroup, resultVariable, creationState );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visitColumns(ColumnConsumer consumer) {
|
||||
entityMappingType.visitColumns( consumer );
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
|||
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
|
||||
import org.hibernate.metamodel.mapping.CollectionMappingType;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
import org.hibernate.metamodel.mapping.ColumnConsumer;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
|
|
|
@ -83,6 +83,7 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
|
|||
private ForeignKeyDescriptor foreignKeyDescriptor;
|
||||
private ForeignKeyDirection foreignKeyDirection;
|
||||
private String identifyingColumnsTableExpression;
|
||||
private boolean isKeyReferringSide;
|
||||
|
||||
public ToOneAttributeMapping(
|
||||
String name,
|
||||
|
@ -184,6 +185,8 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
|
|||
|
||||
public void setForeignKeyDescriptor(ForeignKeyDescriptor foreignKeyDescriptor) {
|
||||
this.foreignKeyDescriptor = foreignKeyDescriptor;
|
||||
assert identifyingColumnsTableExpression != null;
|
||||
isKeyReferringSide = foreignKeyDescriptor.getAssociationKey().getTable().equals( identifyingColumnsTableExpression );
|
||||
}
|
||||
|
||||
public void setIdentifyingColumnsTableExpression(String tableExpression) {
|
||||
|
@ -310,7 +313,7 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
|
|||
|
||||
We have a cirularity but it is not bidirectional
|
||||
*/
|
||||
if ( referringPrimaryKey ) {
|
||||
if ( isKeyReferringSide ) {
|
||||
final TableGroup parentTableGroup = creationState
|
||||
.getSqlAstCreationState()
|
||||
.getFromClauseAccess()
|
||||
|
@ -462,13 +465,13 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
|
|||
*/
|
||||
|
||||
boolean selectByUniqueKey;
|
||||
if ( referringPrimaryKey ) {
|
||||
if ( isKeyReferringSide ) {
|
||||
// case 1.2
|
||||
keyResult = foreignKeyDescriptor.createDomainResult( fetchablePath, parentTableGroup, creationState );
|
||||
selectByUniqueKey = false;
|
||||
}
|
||||
else {
|
||||
keyResult = ((EntityPersister) getDeclaringType()).getIdentifierMapping()
|
||||
keyResult = ( (EntityPersister) getDeclaringType() ).getIdentifierMapping()
|
||||
.createDomainResult( fetchablePath, parentTableGroup, null, creationState );
|
||||
// case 1.1
|
||||
selectByUniqueKey = true;
|
||||
|
@ -616,7 +619,7 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
|
|||
|
||||
@Override
|
||||
public void visitColumns(ColumnConsumer consumer) {
|
||||
if ( foreignKeyDirection == ForeignKeyDirection.FROM_PARENT ) {
|
||||
if ( isKeyReferringSide ) {
|
||||
foreignKeyDescriptor.visitReferringColumns( consumer );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.query.sqm.mutation.internal;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
@ -30,7 +29,6 @@ import org.hibernate.query.sqm.tree.select.SqmSelectClause;
|
|||
import org.hibernate.query.sqm.tree.update.SqmAssignment;
|
||||
import org.hibernate.query.sqm.tree.update.SqmSetClause;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
import org.hibernate.sql.ast.spi.SqlAstProcessingState;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||
|
@ -41,9 +39,6 @@ import org.hibernate.sql.ast.tree.predicate.Predicate;
|
|||
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||
import org.hibernate.sql.ast.tree.update.Assignable;
|
||||
import org.hibernate.sql.ast.tree.update.Assignment;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
|
||||
/**
|
||||
* Specialized BaseSqmToSqlAstConverter implementation used during conversion
|
||||
|
@ -56,7 +51,7 @@ import org.hibernate.sql.results.graph.FetchParent;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class MultiTableSqmMutationConverter extends BaseSqmToSqlAstConverter implements DomainResultCreationState {
|
||||
public class MultiTableSqmMutationConverter extends BaseSqmToSqlAstConverter {
|
||||
private final EntityMappingType mutatingEntityDescriptor;
|
||||
private final TableGroup mutatingTableGroup;
|
||||
|
||||
|
@ -212,16 +207,6 @@ public class MultiTableSqmMutationConverter extends BaseSqmToSqlAstConverter imp
|
|||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public SqlAstCreationState getSqlAstCreationState() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Fetch> visitFetches(FetchParent fetchParent) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public void visitSelectClause(
|
||||
SqmSelectClause sqmSelectClause,
|
||||
QuerySpec sqlQuerySpec,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.query.sqm.sql;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -21,12 +22,10 @@ import org.hibernate.NotYetImplementedFor6Exception;
|
|||
import org.hibernate.dialect.function.TimestampaddFunction;
|
||||
import org.hibernate.dialect.function.TimestampdiffFunction;
|
||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.internal.util.MutableInteger;
|
||||
import org.hibernate.internal.util.collections.Stack;
|
||||
import org.hibernate.internal.util.collections.StandardStack;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
import org.hibernate.metamodel.mapping.ColumnConsumer;
|
||||
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
|
@ -137,6 +136,7 @@ import org.hibernate.sql.ast.spi.FromClauseAccess;
|
|||
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
|
||||
import org.hibernate.sql.ast.spi.SqlAliasBaseManager;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
import org.hibernate.sql.ast.spi.SqlAstProcessingState;
|
||||
import org.hibernate.sql.ast.spi.SqlAstQuerySpecProcessingState;
|
||||
import org.hibernate.sql.ast.spi.SqlAstTreeHelper;
|
||||
|
@ -150,7 +150,6 @@ import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression;
|
|||
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
|
||||
import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression;
|
||||
import org.hibernate.sql.ast.tree.expression.CastTarget;
|
||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||
import org.hibernate.sql.ast.tree.expression.Distinct;
|
||||
import org.hibernate.sql.ast.tree.expression.Duration;
|
||||
import org.hibernate.sql.ast.tree.expression.DurationUnit;
|
||||
|
@ -185,7 +184,9 @@ import org.hibernate.sql.ast.tree.select.SortSpecification;
|
|||
import org.hibernate.sql.exec.internal.JdbcParameterImpl;
|
||||
import org.hibernate.sql.exec.internal.JdbcParametersImpl;
|
||||
import org.hibernate.sql.exec.spi.JdbcParameters;
|
||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
@ -204,7 +205,7 @@ import static org.hibernate.type.spi.TypeConfiguration.isDuration;
|
|||
*/
|
||||
public abstract class BaseSqmToSqlAstConverter
|
||||
extends BaseSemanticQueryWalker
|
||||
implements SqmToSqlAstConverter, JdbcParameterBySqmParameterAccess, FromClauseAccess {
|
||||
implements SqmToSqlAstConverter, JdbcParameterBySqmParameterAccess, FromClauseAccess, DomainResultCreationState {
|
||||
|
||||
private static final Logger log = Logger.getLogger( BaseSqmToSqlAstConverter.class );
|
||||
|
||||
|
@ -2213,6 +2214,15 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
|
||||
private QuerySpec createMemberOfSubQuery(SqmPath<?> pluralPath, PluralAttributeMapping mappingModelExpressable) {
|
||||
final QuerySpec querySpec = new QuerySpec( true );
|
||||
processingStateStack.push(
|
||||
new SqlAstQuerySpecProcessingStateImpl(
|
||||
querySpec,
|
||||
processingStateStack.getCurrent(),
|
||||
this,
|
||||
currentClauseStack::getCurrent
|
||||
)
|
||||
);
|
||||
|
||||
final TableGroup rootTableGroup = mappingModelExpressable.createRootTableGroup(
|
||||
pluralPath.getNavigablePath(),
|
||||
null,
|
||||
|
@ -2223,22 +2233,17 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
() -> querySpec::applyPredicate,
|
||||
creationContext
|
||||
);
|
||||
|
||||
querySpec.getFromClause().addRoot( rootTableGroup );
|
||||
|
||||
final CollectionPart elementDescriptor = mappingModelExpressable.getElementDescriptor();
|
||||
final ColumnConsumer columnConsumer = createMemberOfColumnConsumer( querySpec, rootTableGroup );
|
||||
|
||||
if ( elementDescriptor instanceof EntityCollectionPart ) {
|
||||
( (EntityCollectionPart) elementDescriptor ).getEntityMappingType()
|
||||
.getIdentifierMapping().visitColumns( columnConsumer );
|
||||
}
|
||||
else if ( elementDescriptor instanceof BasicValuedCollectionPart ) {
|
||||
elementDescriptor.visitColumns( columnConsumer );
|
||||
}
|
||||
else {
|
||||
throw new NotYetImplementedFor6Exception(
|
||||
"Member of with Collection of Embeddable has not yet been implemented" );
|
||||
}
|
||||
elementDescriptor.createDomainResult(
|
||||
pluralPath.getNavigablePath(),
|
||||
rootTableGroup,
|
||||
null,
|
||||
this
|
||||
);
|
||||
|
||||
final Predicate predicate = mappingModelExpressable.getKeyDescriptor().generateJoinPredicate(
|
||||
getFromClauseAccess().findTableGroup( pluralPath.getNavigablePath().getParent() ),
|
||||
|
@ -2249,28 +2254,10 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
);
|
||||
querySpec.applyPredicate( predicate );
|
||||
|
||||
processingStateStack.pop();
|
||||
return querySpec;
|
||||
}
|
||||
|
||||
private ColumnConsumer createMemberOfColumnConsumer(QuerySpec querySpec, TableGroup rootTableGroup) {
|
||||
final MutableInteger count = new MutableInteger();
|
||||
return (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> {
|
||||
ColumnReference columnReference = new ColumnReference(
|
||||
rootTableGroup.getPrimaryTableReference(),
|
||||
columnExpression,
|
||||
isColumnExpressionFormula,
|
||||
jdbcMapping,
|
||||
creationContext.getSessionFactory()
|
||||
);
|
||||
|
||||
final int valuesPosition = count.getAndIncrement();
|
||||
|
||||
querySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl( valuesPosition + 1, valuesPosition, columnReference )
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public NegatedPredicate visitNegatedPredicate(SqmNegatedPredicate predicate) {
|
||||
return new NegatedPredicate(
|
||||
|
@ -2453,4 +2440,14 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
public Object visitExistsPredicate(SqmExistsPredicate predicate) {
|
||||
return new ExistsPredicate( (QuerySpec) predicate.getExpression().accept( this ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlAstCreationState getSqlAstCreationState() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Fetch> visitFetches(FetchParent fetchParent) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
*/
|
||||
package org.hibernate.query.sqm.sql.internal;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
|
@ -27,7 +29,6 @@ import org.hibernate.query.sqm.tree.insert.SqmValues;
|
|||
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
|
||||
import org.hibernate.query.sqm.tree.select.SqmSelection;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
|
@ -37,19 +38,13 @@ import org.hibernate.sql.ast.tree.select.QuerySpec;
|
|||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||
import org.hibernate.sql.ast.tree.update.Assignable;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StandardSqmInsertTranslator
|
||||
extends BaseSqmToSqlAstConverter
|
||||
implements SqmInsertTranslator, DomainResultCreationState {
|
||||
implements SqmInsertTranslator {
|
||||
|
||||
private final List<DomainResult> domainResults = CollectionHelper.arrayList( 10 );
|
||||
|
||||
|
@ -229,13 +224,4 @@ public class StandardSqmInsertTranslator
|
|||
return new SelectStatement( querySpec, domainResults );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlAstCreationState getSqlAstCreationState() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Fetch> visitFetches(FetchParent fetchParent) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,6 @@ import org.hibernate.sql.ast.tree.predicate.Predicate;
|
|||
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.EntityGraphTraversalState;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
|
@ -93,7 +92,7 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
|||
@SuppressWarnings("unchecked")
|
||||
public class StandardSqmSelectTranslator
|
||||
extends BaseSqmToSqlAstConverter
|
||||
implements DomainResultCreationState, SqmSelectTranslator {
|
||||
implements SqmSelectTranslator {
|
||||
|
||||
// prepare for 10 root selections to avoid list growth in most cases
|
||||
private final List<DomainResult> domainResults = CollectionHelper.arrayList( 10 );
|
||||
|
|
|
@ -56,7 +56,6 @@ public class StandardSqmUpdateTranslator
|
|||
extends BaseSqmToSqlAstConverter
|
||||
implements SimpleSqmUpdateTranslator {
|
||||
|
||||
|
||||
public StandardSqmUpdateTranslator(
|
||||
SqlAstCreationContext creationContext,
|
||||
QueryOptions queryOptions,
|
||||
|
@ -292,4 +291,5 @@ public class StandardSqmUpdateTranslator
|
|||
|
||||
return assignments;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import javax.persistence.TemporalType;
|
|||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -104,6 +105,17 @@ public class ManyToManyHqlMemberOfQueryTest {
|
|||
);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createQuery( "delete from Call" ).executeUpdate();
|
||||
session.createQuery( "delete from Person" ).executeUpdate();
|
||||
session.createQuery( "delete from Phone" ).executeUpdate();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMemberOf(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
|
@ -155,7 +167,7 @@ public class ManyToManyHqlMemberOfQueryTest {
|
|||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date createdOn;
|
||||
|
||||
@ManyToMany( cascade = CascadeType.ALL)
|
||||
@ManyToMany(cascade = CascadeType.ALL)
|
||||
private List<Phone> phones = new ArrayList<>();
|
||||
|
||||
@ElementCollection
|
||||
|
|
Loading…
Reference in New Issue