From b8b7a0f19b2a32a436cedfd6c3632b3d9c0d7ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Wed, 18 Jul 2018 18:39:39 +0200 Subject: [PATCH] HHH-12492 Qualify references to columns from the target table in subqueries in DELETE/UPDATE queries Don't try to duplicate the logic from org.hibernate.hql.internal.ast.tree.FromElementType#toColumns(java.lang.String, java.lang.String, boolean, boolean) in other classes, it's complex enough and already seems to handle all the cases we might encounter. In this specific case, we want the table name to be used to qualify column names, because the target table doesn't have any alias (it's not supported by every version of every RDBMS), and not qualifying columns at all may lead to a confusing statement, in particular if tables referenced in the subquery contain columns with the same name. Since we use aliases for every other table in the query, referencing the table should not lead to any conflict. --- .../hibernate/hql/internal/ast/tree/FromElement.java | 10 ++++------ .../org/hibernate/hql/internal/ast/tree/IdentNode.java | 8 -------- ...leteQuerySubqueryReferencingTargetPropertyTest.java | 2 -- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElement.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElement.java index bb47d0e090..1b0affe726 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElement.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElement.java @@ -341,12 +341,10 @@ public class FromElement extends HqlSqlWalkerNode implements DisplayableNode, Pa final String propertyName = getIdentifierPropertyName(); - if ( getWalker().getStatementType() == HqlSqlTokenTypes.SELECT ) { - return getPropertyMapping( propertyName ).toColumns( table, propertyName ); - } - else { - return getPropertyMapping( propertyName ).toColumns( propertyName ); - } + return toColumns( + table, propertyName, + getWalker().getStatementType() == HqlSqlTokenTypes.SELECT + ); } public void setCollectionJoin(boolean collectionJoin) { diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/IdentNode.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/IdentNode.java index 81a26186c3..1574c57feb 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/IdentNode.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/IdentNode.java @@ -197,14 +197,6 @@ public class IdentNode extends FromReferenceNode implements SelectExpression { String[] columnExpressions = element.getIdentityColumns(); - // determine whether to apply qualification (table alias) to the column(s)... - if ( ! isFromElementUpdateOrDeleteRoot( element ) ) { - if ( StringHelper.isNotEmpty( element.getTableAlias() ) ) { - // apparently we also need to check that they are not already qualified. Ugh! - columnExpressions = StringHelper.qualifyIfNot( element.getTableAlias(), columnExpressions ); - } - } - final Dialect dialect = getWalker().getSessionFactoryHelper().getFactory().getDialect(); final boolean isInCount = getWalker().isInCount(); final boolean isInDistinctCount = isInCount && getWalker().isInCountDistinct(); diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/DeleteQuerySubqueryReferencingTargetPropertyTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/DeleteQuerySubqueryReferencingTargetPropertyTest.java index 3d91f66620..9e2be86721 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/DeleteQuerySubqueryReferencingTargetPropertyTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/hql/DeleteQuerySubqueryReferencingTargetPropertyTest.java @@ -10,7 +10,6 @@ import javax.persistence.criteria.CriteriaQuery; import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; -import org.hibernate.testing.FailureExpected; import org.hibernate.testing.TestForIssue; import org.junit.Assert; import org.junit.Test; @@ -26,7 +25,6 @@ public class DeleteQuerySubqueryReferencingTargetPropertyTest extends BaseEntity } @Test - @FailureExpected(jiraKey = "HHH-12492") public void testSubQueryReferencingTargetProperty() { // prepare doInJPA( this::entityManagerFactory, entityManager -> {