diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElementType.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElementType.java index 0f312e183e..1d61651705 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElementType.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElementType.java @@ -457,7 +457,7 @@ class FromElementType { // table name as the column qualification // 2) otherwise (not correlated), use the given alias if ( isCorrelation() ) { - if ( isMultiTable() ) { + if ( isMultiTable() || isInsertQuery() ) { return propertyMapping.toColumns( tableAlias, path ); } return propertyMapping.toColumns( extractTableName(), path ); @@ -498,6 +498,10 @@ class FromElementType { return fromElement.getQueryable().getTableName(); } + private boolean isInsertQuery() { + return fromElement.getWalker().getStatementType() == HqlSqlTokenTypes.INSERT; + } + private boolean isManipulationQuery() { return fromElement.getWalker().getStatementType() == HqlSqlTokenTypes.UPDATE || fromElement.getWalker().getStatementType() == HqlSqlTokenTypes.DELETE; diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/InsertWithSubSelectTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/InsertWithSubSelectTest.java new file mode 100644 index 0000000000..d07ad16451 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/hql/InsertWithSubSelectTest.java @@ -0,0 +1,118 @@ +/* + * 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 . + */ +package org.hibernate.test.hql; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import org.hibernate.QueryException; +import org.hibernate.Session; +import org.hibernate.Transaction; + +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; + +import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; +import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; +import static org.junit.Assert.fail; + +/** + * @author bjoern.moritz + */ +public class InsertWithSubSelectTest extends BaseCoreFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { + A.class, + B.class, + C.class + }; + } + + @Test + public void testInsert() { + doInHibernate( this::sessionFactory, session -> { + session.createQuery( + "insert into C (id) " + + "select a.id from A a " + + "where exists (" + + " select 1 " + + " from B b " + + " where b.id = a.id" + + ")" + ) + .executeUpdate(); + } ); + } + + @Test + public void testSelect() { + doInHibernate( this::sessionFactory, session -> { + session.createQuery( + "select a.id " + + "from A a " + + "where exists (" + + " select 1 " + + " from B b " + + " where b.id = a.id" + + ")" + ) + .getResultList(); + } ); + } + + @Entity(name = "A") + public static class A { + + @Id + @GeneratedValue + private Integer id; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + } + + @Entity(name = "B") + public static class B { + + @Id + @GeneratedValue + private Integer id; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + } + + @Entity(name = "C") + public static class C { + + @Id + @GeneratedValue + private Integer id; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + } + +}