6 - SQM based on JPA type system

- DynamicInstantiationTests
This commit is contained in:
Steve Ebersole 2019-07-25 14:17:27 -05:00 committed by Andrea Boriero
parent 5e8be067ca
commit 21f4cfb891
6 changed files with 268 additions and 75 deletions

View File

@ -4,10 +4,11 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later * 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 * 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 java.util.List;
import org.hibernate.orm.test.query.sqm.BaseSqmUnitTest;
import org.hibernate.query.sqm.AliasCollisionException; import org.hibernate.query.sqm.AliasCollisionException;
import org.hibernate.query.sqm.produce.spi.ImplicitAliasGenerator; import org.hibernate.query.sqm.produce.spi.ImplicitAliasGenerator;
import org.hibernate.query.sqm.tree.domain.SqmNavigableReference; import org.hibernate.query.sqm.tree.domain.SqmNavigableReference;

View File

@ -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 ) );
}
}

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later * 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 * 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.boot.MetadataSources;
import org.hibernate.jpa.spi.JpaCompliance; import org.hibernate.jpa.spi.JpaCompliance;

View File

@ -4,10 +4,11 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later * 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 * 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 java.util.List;
import org.hibernate.orm.test.query.sqm.BaseSqmUnitTest;
import org.hibernate.orm.test.query.sqm.domain.Person; import org.hibernate.orm.test.query.sqm.domain.Person;
import org.hibernate.query.SemanticException; import org.hibernate.query.SemanticException;
import org.hibernate.query.sqm.tree.SqmJoinType; import org.hibernate.query.sqm.tree.SqmJoinType;

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later * 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 * 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; import javax.money.MonetaryAmount;

View File

@ -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() )
);
}
}