diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/path/AbstractFromImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/path/AbstractFromImpl.java index 238b81076d..6dce4681c1 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/path/AbstractFromImpl.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/path/AbstractFromImpl.java @@ -194,11 +194,19 @@ public abstract class AbstractFromImpl @Override public boolean isCorrelated() { - return getCorrelationParent() != null; + return correlationParent != null; } @Override public FromImplementor getCorrelationParent() { + if ( correlationParent == null ) { + throw new IllegalStateException( + String.format( + "Criteria query From node [%s] is not part of a subquery correlation", + getPathIdentifier() + ) + ); + } return correlationParent; } diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/criteria/subquery/UncorrelatedSubqueryTest.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/criteria/subquery/UncorrelatedSubqueryTest.java index c3282b5e38..9e8b491f11 100644 --- a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/criteria/subquery/UncorrelatedSubqueryTest.java +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/criteria/subquery/UncorrelatedSubqueryTest.java @@ -38,12 +38,52 @@ import org.hibernate.jpa.test.metamodel.Order_; import org.junit.Test; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.fail; /** * @author Steve Ebersole */ public class UncorrelatedSubqueryTest extends AbstractMetamodelSpecificTest { + @Test + public void testGetCorrelatedParentIllegalStateException() { + // test that attempting to call getCorrelatedParent on a uncorrelated query/subquery + // throws ISE + + CriteriaBuilder builder = entityManagerFactory().getCriteriaBuilder(); + EntityManager em = getOrCreateEntityManager(); + em.getTransaction().begin(); + + CriteriaQuery criteria = builder.createQuery( Customer.class ); + Root customerRoot = criteria.from( Customer.class ); + Join orderJoin = customerRoot.join( Customer_.orders ); + criteria.select( customerRoot ); + Subquery subCriteria = criteria.subquery( Double.class ); + Root subqueryOrderRoot = subCriteria.from( Order.class ); + subCriteria.select( builder.min( subqueryOrderRoot.get( Order_.totalPrice ) ) ); + criteria.where( builder.equal( orderJoin.get( "totalPrice" ), builder.all( subCriteria ) ) ); + + assertFalse( customerRoot.isCorrelated() ); + assertFalse( subqueryOrderRoot.isCorrelated() ); + + try { + customerRoot.getCorrelationParent(); + fail( "Should have resulted in IllegalStateException" ); + } + catch (IllegalStateException expected) { + } + + try { + subqueryOrderRoot.getCorrelationParent(); + fail( "Should have resulted in IllegalStateException" ); + } + catch (IllegalStateException expected) { + } + + em.getTransaction().commit(); + em.close(); + } + @Test public void testEqualAll() { CriteriaBuilder builder = entityManagerFactory().getCriteriaBuilder();