diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/AliasCollisionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/AliasCollisionTest.java similarity index 98% rename from hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/AliasCollisionTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/AliasCollisionTest.java index c7aeacb612..5af7adcc81 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/AliasCollisionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/AliasCollisionTest.java @@ -4,10 +4,11 @@ * 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.orm.test.query.sqm; +package org.hibernate.orm.test.query.hql; import java.util.List; +import org.hibernate.orm.test.query.sqm.BaseSqmUnitTest; import org.hibernate.query.sqm.AliasCollisionException; import org.hibernate.query.sqm.produce.spi.ImplicitAliasGenerator; import org.hibernate.query.sqm.tree.domain.SqmNavigableReference; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/DynamicInstantiationTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/DynamicInstantiationTests.java new file mode 100644 index 0000000000..4c292e09fa --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/DynamicInstantiationTests.java @@ -0,0 +1,262 @@ +/* + * 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.orm.test.query.hql; + +import java.util.List; +import java.util.Map; + +import org.hibernate.orm.test.query.sqm.BaseSqmUnitTest; +import org.hibernate.orm.test.query.sqm.domain.ConstructedLookupListItem; +import org.hibernate.orm.test.query.sqm.domain.InjectedLookupListItem; +import org.hibernate.orm.test.query.sqm.domain.NestedCtorLookupListItem; +import org.hibernate.query.DynamicInstantiationNature; +import org.hibernate.query.sqm.tree.domain.SqmPath; +import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation; +import org.hibernate.query.sqm.tree.select.SqmSelectStatement; + +import org.hibernate.testing.orm.domain.gambit.EntityOfBasics; +import org.hibernate.testing.orm.junit.TestingUtil; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hibernate.testing.hamcrest.CollectionMatchers.hasSize; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * @author Steve Ebersole + */ +@SuppressWarnings("WeakerAccess") +public class DynamicInstantiationTests extends BaseSqmUnitTest { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { + EntityOfBasics.class, + }; + } + + @Test + public void testSimpleDynamicInstantiationSelection() { + SqmSelectStatement statement = interpretSelect( + "select new org.hibernate.orm.test.query.sqm.domain.ConstructedLookupListItem( e.id, e.theString ) from EntityOfBasics e" + ); + assertEquals( 1, statement.getQuerySpec().getSelectClause().getSelections().size() ); + + final SqmDynamicInstantiation dynamicInstantiation = TestingUtil.cast( + statement.getQuerySpec().getSelectClause().getSelections().get( 0 ).getSelectableNode(), + SqmDynamicInstantiation.class + ); + + assertThat( dynamicInstantiation.getInstantiationTarget().getNature(), is( DynamicInstantiationNature.CLASS ) ); + assertThat( dynamicInstantiation.getInstantiationTarget().getJavaType(), is( equalTo( ConstructedLookupListItem.class ) ) ); + assertThat( dynamicInstantiation.getArguments(), hasSize( 2 ) ); + } + + @Test + public void testMultipleDynamicInstantiationSelection() { + SqmSelectStatement statement = interpretSelect( + "select new org.hibernate.orm.test.query.sqm.domain.ConstructedLookupListItem( e.id, e.theString ), " + + "new org.hibernate.orm.test.query.sqm.domain.ConstructedLookupListItem( e.id, e.theString ) " + + "from EntityOfBasics e" + ); + assertEquals( 2, statement.getQuerySpec().getSelectClause().getSelections().size() ); + + + { + final SqmDynamicInstantiation instantiation = TestingUtil.cast( + statement.getQuerySpec().getSelectClause().getSelections().get( 0 ).getSelectableNode(), + SqmDynamicInstantiation.class + ); + assertThat( instantiation.getInstantiationTarget().getNature(), is( DynamicInstantiationNature.CLASS ) ); + assertThat( + instantiation.getInstantiationTarget().getJavaType(), + is( equalTo( ConstructedLookupListItem.class ) ) + ); + assertThat( instantiation.getArguments(), hasSize( 2 ) ); + } + + { + final SqmDynamicInstantiation instantiation = TestingUtil.cast( + statement.getQuerySpec().getSelectClause().getSelections().get( 1 ).getSelectableNode(), + SqmDynamicInstantiation.class + ); + assertThat( instantiation.getInstantiationTarget().getNature(), is( DynamicInstantiationNature.CLASS ) ); + assertThat( + instantiation.getInstantiationTarget().getJavaType(), + is( equalTo( ConstructedLookupListItem.class ) ) + ); + assertThat( instantiation.getArguments(), hasSize( 2 ) ); + } + } + + @Test + public void testMixedAttributeAndDynamicInstantiationSelection() { + SqmSelectStatement statement = interpretSelect( + "select new org.hibernate.orm.test.query.sqm.domain.ConstructedLookupListItem( e.id, e.theString ), e.theInteger from EntityOfBasics e" + ); + assertEquals( 2, statement.getQuerySpec().getSelectClause().getSelections().size() ); + + + final SqmDynamicInstantiation instantiation = TestingUtil.cast( + statement.getQuerySpec().getSelectClause().getSelections().get( 0 ).getSelectableNode(), + SqmDynamicInstantiation.class + ); + assertThat( instantiation.getInstantiationTarget().getNature(), is( DynamicInstantiationNature.CLASS ) ); + assertThat( + instantiation.getInstantiationTarget().getJavaType(), + is( equalTo( ConstructedLookupListItem.class ) ) + ); + assertThat( instantiation.getArguments(), hasSize( 2 ) ); + + + final SqmPath theIntegerPath = TestingUtil.cast( + statement.getQuerySpec().getSelectClause().getSelections().get( 1 ).getSelectableNode(), + SqmPath.class + ); + assertThat( theIntegerPath.getReferencedPathSource().getPathName(), is( "theInteger" ) ); + assertThat( theIntegerPath.getReferencedPathSource().getBindableJavaType(), is( equalTo( Integer.class ) ) ); + } + + @Test + public void testNestedDynamicInstantiationSelection() { + SqmSelectStatement statement = interpretSelect( + "select new org.hibernate.orm.test.query.sqm.domain.NestedCtorLookupListItem(" + + " e.id, " + + " e.theString, " + + " new org.hibernate.orm.test.query.sqm.domain.ConstructedLookupListItem( e.id, e.theString )" + + " ) " + + " from EntityOfBasics e" + ); + assertEquals( 1, statement.getQuerySpec().getSelectClause().getSelections().size() ); + + final SqmDynamicInstantiation instantiation = TestingUtil.cast( + statement.getQuerySpec().getSelectClause().getSelections().get( 0 ).getSelectableNode(), + SqmDynamicInstantiation.class + ); + assertThat( instantiation.getInstantiationTarget().getNature(), is( DynamicInstantiationNature.CLASS ) ); + assertThat( + instantiation.getInstantiationTarget().getJavaType(), + is( equalTo( NestedCtorLookupListItem.class ) ) + ); + assertThat( instantiation.getArguments(), hasSize( 3 ) ); + + final SqmPath firstArg = TestingUtil.cast( + instantiation.getArguments().get( 0 ).getSelectableNode(), + SqmPath.class + ); + assertThat( firstArg.getReferencedPathSource().getPathName(), is( "id" ) ); + + final SqmPath secondArg = TestingUtil.cast( + instantiation.getArguments().get( 1 ).getSelectableNode(), + SqmPath.class + ); + assertThat( secondArg.getReferencedPathSource().getPathName(), is( "theString" ) ); + + + final SqmDynamicInstantiation thirdArg = TestingUtil.cast( + instantiation.getArguments().get( 2 ).getSelectableNode(), + SqmDynamicInstantiation.class + ); + assertThat( thirdArg.getInstantiationTarget().getNature(), is( DynamicInstantiationNature.CLASS ) ); + assertThat( + thirdArg.getInstantiationTarget().getJavaType(), + is( equalTo( ConstructedLookupListItem.class ) ) + ); + assertThat( thirdArg.getArguments(), hasSize( 2 ) ); + } + + @Test + public void testSimpleDynamicListInstantiation() { + SqmSelectStatement statement = interpretSelect( "select new list( e.id, e.theString ) from EntityOfBasics e" ); + assertEquals( 1, statement.getQuerySpec().getSelectClause().getSelections().size() ); + + final SqmDynamicInstantiation instantiation = TestingUtil.cast( + statement.getQuerySpec().getSelectClause().getSelections().get( 0 ).getSelectableNode(), + SqmDynamicInstantiation.class + ); + assertThat( + instantiation.getInstantiationTarget().getNature(), + equalTo( DynamicInstantiationNature.LIST ) + ); + assertThat( + instantiation.getInstantiationTarget().getJavaType(), + is( equalTo( List.class ) ) + ); + + assertThat( instantiation.getArguments(), hasSize( 2 ) ); + + assertThat( + instantiation.getArguments().get( 0 ).getSelectableNode(), + instanceOf( SqmPath.class ) + ); + assertThat( instantiation.getArguments().get( 0 ).getAlias(), is( nullValue() ) ); + + assertThat( + instantiation.getArguments().get( 1 ).getSelectableNode(), + instanceOf( SqmPath.class ) + ); + assertThat( instantiation.getArguments().get( 1 ).getAlias(), is( nullValue() ) ); + } + + @Test + public void testSimpleDynamicMapInstantiation() { + SqmSelectStatement statement = interpretSelect( "select new map( e.id as id, e.theString as ts ) from EntityOfBasics e" ); + assertEquals( 1, statement.getQuerySpec().getSelectClause().getSelections().size() ); + + final SqmDynamicInstantiation instantiation = TestingUtil.cast( + statement.getQuerySpec().getSelectClause().getSelections().get( 0 ).getSelectableNode(), + SqmDynamicInstantiation.class + ); + + assertThat( + instantiation.getInstantiationTarget().getNature(), + equalTo( DynamicInstantiationNature.MAP ) + ); + assertThat( + instantiation.getInstantiationTarget().getJavaType(), + is( equalTo( Map.class ) ) + ); + + assertEquals( 2, instantiation.getArguments().size() ); + + assertThat( + instantiation.getArguments().get( 0 ).getSelectableNode(), + instanceOf( SqmPath.class ) + ); + assertThat( instantiation.getArguments().get( 0 ).getAlias(), is( "id" ) ); + + assertThat( + instantiation.getArguments().get( 1 ).getSelectableNode(), + instanceOf( SqmPath.class ) + ); + assertThat( instantiation.getArguments().get( 1 ).getAlias(), is( "ts" ) ); + } + + @Test + public void testSimpleInjectedInstantiation() { + // todo (6.0) : this should blow up as early as possible - no aliases for bean-injection-based dynamic-instantiation + // atm this does not fail until later when building the SQL AST + + SqmSelectStatement statement = interpretSelect( + "select new org.hibernate.orm.test.query.sqm.domain.InjectedLookupListItem( e.id, e.theString ) from EntityOfBasics e" + ); + assertEquals( 1, statement.getQuerySpec().getSelectClause().getSelections().size() ); + + final SqmDynamicInstantiation dynamicInstantiation = TestingUtil.cast( + statement.getQuerySpec().getSelectClause().getSelections().get( 0 ).getSelectableNode(), + SqmDynamicInstantiation.class + ); + + assertThat( dynamicInstantiation.getInstantiationTarget().getNature(), is( DynamicInstantiationNature.CLASS ) ); + assertThat( dynamicInstantiation.getInstantiationTarget().getJavaType(), is( equalTo( InjectedLookupListItem.class ) ) ); + assertThat( dynamicInstantiation.getArguments(), hasSize( 2 ) ); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/ExtensionSqmInferenceTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/ExtensionSqmInferenceTests.java similarity index 96% rename from hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/ExtensionSqmInferenceTests.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/ExtensionSqmInferenceTests.java index f00ae9b8b6..e477e997be 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/ExtensionSqmInferenceTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/ExtensionSqmInferenceTests.java @@ -4,7 +4,7 @@ * 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.orm.test.query.sqm; +package org.hibernate.orm.test.query.hql; import org.hibernate.boot.MetadataSources; import org.hibernate.jpa.spi.JpaCompliance; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/FromClauseTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FromClauseTests.java similarity index 98% rename from hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/FromClauseTests.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FromClauseTests.java index cf68e53f8d..5c9605ff3b 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/FromClauseTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FromClauseTests.java @@ -4,10 +4,11 @@ * 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.orm.test.query.sqm; +package org.hibernate.orm.test.query.hql; import java.util.List; +import org.hibernate.orm.test.query.sqm.BaseSqmUnitTest; import org.hibernate.orm.test.query.sqm.domain.Person; import org.hibernate.query.SemanticException; import org.hibernate.query.sqm.tree.SqmJoinType; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/JpaStandardSqmInferenceTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/JpaStandardSqmInferenceTests.java similarity index 98% rename from hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/JpaStandardSqmInferenceTests.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/JpaStandardSqmInferenceTests.java index fa1c498d5a..9cca4f4012 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/JpaStandardSqmInferenceTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/JpaStandardSqmInferenceTests.java @@ -4,7 +4,7 @@ * 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.orm.test.query.sqm; +package org.hibernate.orm.test.query.hql; import javax.money.MonetaryAmount; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/FirstSqmUnitTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/FirstSqmUnitTest.java deleted file mode 100644 index b182bd80e4..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/FirstSqmUnitTest.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.orm.test.query.sqm; - -import javax.persistence.Entity; -import javax.persistence.Id; - -import org.hibernate.query.sqm.tree.select.SqmSelectStatement; - -import org.junit.jupiter.api.Test; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.MatcherAssert.assertThat; - -/** - * @author Steve Ebersole - */ -public class FirstSqmUnitTest extends BaseSqmUnitTest { - - // todo (6.0) : this test can likely just go away ultimately. - // it was intended just as a simple first "smoke" test - - @Entity( name = "Person" ) - public static class Person { - @Id - public Integer id; - public String name; - } - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { - Person.class - }; - } - - @Test - public void testSelectRoot() { - final SqmSelectStatement sqm = interpretSelect( "select p from Person p" ); - - assertThat( sqm, notNullValue() ); - assertThat( - sqm.getQuerySpec().getFromClause().getRoots().size(), - is( 1 ) - ); - assertThat( - sqm.getQuerySpec().getFromClause().getRoots().get( 0 ).getEntityName(), - is( sessionFactory().getMetamodel().findEntityDescriptor( Person.class ).getEntityName() ) - ); - } - - @Test - public void testSelectId() { - final SqmSelectStatement sqm = interpretSelect( "select p.id from Person p" ); - - assertThat( sqm, notNullValue() ); - assertThat( - sqm.getQuerySpec().getFromClause().getRoots().size(), - is( 1 ) - ); - assertThat( - sqm.getQuerySpec().getFromClause().getRoots().get( 0 ).getEntityName(), - is( sessionFactory().getMetamodel().findEntityDescriptor( Person.class ).getEntityName() ) - ); - } -}