From a692061ae117f96609e818b5af49a084db860c15 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 30 Mar 2021 08:47:16 -0500 Subject: [PATCH] re-enable tests re-organize some tests fixed edge case for implicit basic type resolution --- .../internal/InferredBasicValueResolver.java | 45 +- .../org/hibernate/mapping/BasicValue.java | 28 +- .../AggregateFunctionsWithSubSelectTest.java | 242 +++++++++ ...veElementCollectionAndAssociationTest.java | 85 ++++ .../query/hql/InsertWithSubSelectTest.java | 114 +++++ .../QueryParametersValidationArrayTest.java | 48 +- .../hql/QueryParametersValidationTest.java | 43 ++ .../test/query/hql/ToOneFetchAndJoinTest.java | 176 +++++++ ...hPackageNamesStartingWithKeywordsTest.java | 6 +- .../UpdateEntityWithEmbeddedTest.java | 54 +- .../AggregateFunctionsWithSubSelectTest.java | 230 --------- .../CollectionJoinSubQueryWithClauseTest.java | 66 +++ .../test/hql/CountExpressionTest.java | 2 +- ...veElementCollectionAndAssociationTest.java | 70 --- .../test/hql/InsertWithSubSelectTest.java | 114 ----- .../hql/QueryParametersValidationTest.java | 45 -- .../hql/ScrollableCollectionFetchingTest.java | 1 - .../hibernate/test/hql/WithClauseTest.java | 475 ++++++++---------- .../fetchAndJoin/ToOneFetchAndJoinTest.java | 159 ------ 19 files changed, 1031 insertions(+), 972 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/AggregateFunctionsWithSubSelectTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FetchNonRootRelativeElementCollectionAndAssociationTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/InsertWithSubSelectTest.java rename hibernate-core/src/test/java/org/hibernate/{test => orm/test/query}/hql/QueryParametersValidationArrayTest.java (84%) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/QueryParametersValidationTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/ToOneFetchAndJoinTest.java rename hibernate-core/src/test/java/org/hibernate/{test/hql => orm/test/query/hql/mutation}/UpdateEntitiesWithPackageNamesStartingWithKeywordsTest.java (95%) rename hibernate-core/src/test/java/org/hibernate/{test/hql => orm/test/query/hql/mutation}/UpdateEntityWithEmbeddedTest.java (67%) delete mode 100644 hibernate-core/src/test/java/org/hibernate/test/hql/AggregateFunctionsWithSubSelectTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/hql/CollectionJoinSubQueryWithClauseTest.java delete mode 100644 hibernate-core/src/test/java/org/hibernate/test/hql/FetchNonRootRelativeElementCollectionAndAssociationTest.java delete mode 100644 hibernate-core/src/test/java/org/hibernate/test/hql/InsertWithSubSelectTest.java delete mode 100644 hibernate-core/src/test/java/org/hibernate/test/hql/QueryParametersValidationTest.java delete mode 100644 hibernate-core/src/test/java/org/hibernate/test/hql/fetchAndJoin/ToOneFetchAndJoinTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/process/internal/InferredBasicValueResolver.java b/hibernate-core/src/main/java/org/hibernate/boot/model/process/internal/InferredBasicValueResolver.java index 52c9645a22..1f0c1f13d9 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/process/internal/InferredBasicValueResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/process/internal/InferredBasicValueResolver.java @@ -21,11 +21,13 @@ import org.hibernate.metamodel.model.convert.internal.OrdinalEnumValueConverter; import org.hibernate.metamodel.model.domain.AllowableTemporalParameterType; import org.hibernate.type.BasicType; import org.hibernate.type.CustomType; +import org.hibernate.type.SerializableType; import org.hibernate.type.SqlTypeDescriptorIndicatorCapable; import org.hibernate.type.descriptor.java.BasicJavaDescriptor; import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor; import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; +import org.hibernate.type.descriptor.java.SerializableTypeDescriptor; import org.hibernate.type.descriptor.java.TemporalJavaTypeDescriptor; import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor; import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators; @@ -33,7 +35,8 @@ import org.hibernate.type.descriptor.jdbc.TinyIntTypeDescriptor; import org.hibernate.type.spi.TypeConfiguration; /** - * @author Steve Ebersole + * BasicValue.Resolution resolver for cases where no explicit + * type info was supplied. */ public class InferredBasicValueResolver { /** @@ -102,10 +105,43 @@ public class InferredBasicValueResolver { // here we have the legacy case // - we mimic how this used to be done final BasicType registeredType = typeConfiguration.getBasicTypeRegistry().getRegisteredType( reflectedJtd.getJavaType() ); - legacyType = resolveSqlTypeIndicators( stdIndicators, registeredType ); - // reuse the "legacy type" - jdbcMapping = legacyType; + if ( registeredType != null ) { + // reuse the "legacy type" + legacyType = resolveSqlTypeIndicators( stdIndicators, registeredType ); + jdbcMapping = legacyType; + } + else { + // Use JTD if we know it to apply any specialized resolutions + + if ( reflectedJtd instanceof EnumJavaTypeDescriptor ) { + return fromEnum( + (EnumJavaTypeDescriptor) reflectedJtd, + explicitJavaTypeAccess.apply( typeConfiguration ), + explicitSqlTypeAccess.apply( typeConfiguration ), + stdIndicators, + typeConfiguration + ); + } + else if ( reflectedJtd instanceof TemporalJavaTypeDescriptor ) { + return fromTemporal( + (TemporalJavaTypeDescriptor) reflectedJtd, + explicitJavaTypeAccess, + explicitSqlTypeAccess, + stdIndicators, + typeConfiguration + ); + } + else if ( reflectedJtd instanceof SerializableTypeDescriptor ) { + legacyType = new SerializableType<>( reflectedJtd.getJavaTypeClass() ); + jdbcMapping = legacyType; + } + else { + // let this fall through to the exception creation below + legacyType = null; + jdbcMapping = null; + } + } } } else { @@ -120,7 +156,6 @@ public class InferredBasicValueResolver { jdbcMapping = resolveSqlTypeIndicators( stdIndicators, resolved ); legacyType = jdbcMapping; - } else { // we have neither a JTD nor STD diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/BasicValue.java b/hibernate-core/src/main/java/org/hibernate/mapping/BasicValue.java index 7f17a57fcf..755f1f7838 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/BasicValue.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/BasicValue.java @@ -14,6 +14,7 @@ import javax.persistence.TemporalType; import org.hibernate.MappingException; import org.hibernate.boot.model.TypeDefinition; +import org.hibernate.boot.model.TypeDefinitionRegistry; import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor; import org.hibernate.boot.model.convert.spi.ConverterDescriptor; import org.hibernate.boot.model.convert.spi.JpaAttributeConverterCreationContext; @@ -360,11 +361,8 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat } } - - // Use JTD if we know it to apply any specialized resolutions - - final TypeDefinition autoAppliedTypeDef = getBuildingContext().getTypeDefinitionRegistry() - .resolveAutoApplied( (BasicJavaDescriptor) jtd ); + final TypeDefinitionRegistry typeDefinitionRegistry = getBuildingContext().getTypeDefinitionRegistry(); + final TypeDefinition autoAppliedTypeDef = typeDefinitionRegistry.resolveAutoApplied( (BasicJavaDescriptor) jtd ); if ( autoAppliedTypeDef != null ) { log.debug( "BasicValue resolution matched auto-applied type-definition" ); return autoAppliedTypeDef.resolve( @@ -375,26 +373,6 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat ); } - if ( jtd instanceof EnumJavaTypeDescriptor ) { - return InferredBasicValueResolver.fromEnum( - (EnumJavaTypeDescriptor) jtd, - explicitJavaTypeAccess.apply( typeConfiguration ), - explicitSqlTypeAccess.apply( typeConfiguration ), - this, - typeConfiguration - ); - } - - if ( jtd instanceof TemporalJavaTypeDescriptor ) { - return InferredBasicValueResolver.fromTemporal( - (TemporalJavaTypeDescriptor) jtd, - explicitJavaTypeAccess, - explicitSqlTypeAccess, - this, - typeConfiguration - ); - } - return InferredBasicValueResolver.from( explicitJavaTypeAccess, explicitSqlTypeAccess, diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/AggregateFunctionsWithSubSelectTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/AggregateFunctionsWithSubSelectTest.java new file mode 100644 index 0000000000..f2fb720f49 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/AggregateFunctionsWithSubSelectTest.java @@ -0,0 +1,242 @@ +/* + * 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.HashMap; +import java.util.List; +import java.util.Map; +import javax.persistence.CollectionTable; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.MapKeyColumn; +import javax.persistence.OneToMany; + +import org.hibernate.dialect.H2Dialect; + +import org.hibernate.testing.RequiresDialect; +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author bjoern.moritz + */ +@TestForIssue(jiraKey = "HHH-9331") +@RequiresDialect(H2Dialect.class) +@DomainModel( + annotatedClasses = { + AggregateFunctionsWithSubSelectTest.Document.class, + AggregateFunctionsWithSubSelectTest.Person.class + } +) +@SessionFactory +public class AggregateFunctionsWithSubSelectTest { + @BeforeEach + protected void prepareTest(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + Document document = new Document(); + document.setId( 1 ); + + Person p1 = new Person(); + Person p2 = new Person(); + + p1.getLocalized().put(1, "p1.1"); + p1.getLocalized().put(2, "p1.2"); + p2.getLocalized().put(1, "p2.1"); + p2.getLocalized().put(2, "p2.2"); + + document.getContacts().put(1, p1); + document.getContacts().put(2, p2); + + session.persist(p1); + session.persist(p2); + session.persist(document); + } + ); + } + + @AfterEach + public void dropTestData(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + session.createQuery( "delete Document" ).executeUpdate(); + session.createQuery( "delete Person" ).executeUpdate(); + } + ); + } + + @Test + public void testSum(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + List results = session.createQuery( + "SELECT " + + " d.id, " + + " SUM(" + + " (" + + " SELECT COUNT(localized) " + + " FROM Person p " + + " LEFT JOIN p.localized localized " + + " WHERE p.id = c.id" + + " )" + + " ) AS localizedCount " + + "FROM Document d " + + "LEFT JOIN d.contacts c " + + "GROUP BY d.id") + .getResultList(); + + assertEquals(1, results.size()); + Object[] tuple = (Object[]) results.get( 0 ); + assertEquals(1, tuple[0]); + } + ); + } + + @Test + public void testMin(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + List results = session.createQuery( + "SELECT " + + " d.id, " + + " MIN(" + + " (" + + " SELECT COUNT(localized) " + + " FROM Person p " + + " LEFT JOIN p.localized localized " + + " WHERE p.id = c.id" + + " )" + + " ) AS localizedCount " + + "FROM Document d " + + "LEFT JOIN d.contacts c " + + "GROUP BY d.id") + .getResultList(); + + assertEquals(1, results.size()); + Object[] tuple = (Object[]) results.get( 0 ); + assertEquals(1, tuple[0]); + } + ); + } + + @Test + public void testMax(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + final String qry = "SELECT " + + " d.id, " + + " MAX(" + + " (" + + " SELECT COUNT(localized) " + + " FROM Person p " + + " LEFT JOIN p.localized localized " + + " WHERE p.id = c.id" + + " )" + + " ) AS localizedCount " + + "FROM Document d " + + "LEFT JOIN d.contacts c " + + "GROUP BY d.id"; + List results = session.createQuery( qry ).getResultList(); + + assertEquals(1, results.size()); + Object[] tuple = (Object[]) results.get( 0 ); + assertEquals(1, tuple[0]); + } + ); + } + + @Test + public void testAvg(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + final String qry = "SELECT " + + " d.id, " + + " AVG(" + + " (" + + " SELECT COUNT(localized) " + + " FROM Person p " + + " LEFT JOIN p.localized localized " + + " WHERE p.id = c.id" + + " )" + + " ) AS localizedCount " + + "FROM Document d " + + "LEFT JOIN d.contacts c " + + "GROUP BY d.id"; + List results = session.createQuery( qry ).getResultList(); + + assertEquals(1, results.size()); + Object[] tuple = (Object[]) results.get( 0 ); + assertEquals(1, tuple[0]); + } + ); + } + + @Entity(name = "Document") + public static class Document { + + private Integer id; + private Map contacts = new HashMap<>(); + + @Id + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @OneToMany + @CollectionTable + @MapKeyColumn(name = "position") + public Map getContacts() { + return contacts; + } + + public void setContacts(Map contacts) { + this.contacts = contacts; + } + } + + + @Entity(name = "Person") + public static class Person { + + private Integer id; + + private Map localized = new HashMap<>(); + + @Id + @GeneratedValue + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @ElementCollection + public Map getLocalized() { + return localized; + } + + public void setLocalized(Map localized) { + this.localized = localized; + } + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FetchNonRootRelativeElementCollectionAndAssociationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FetchNonRootRelativeElementCollectionAndAssociationTest.java new file mode 100644 index 0000000000..ede1c09619 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FetchNonRootRelativeElementCollectionAndAssociationTest.java @@ -0,0 +1,85 @@ +/* + * 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.HashMap; +import java.util.Map; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.MapsId; +import javax.persistence.OneToOne; +import javax.persistence.Query; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; +import org.hibernate.testing.orm.junit.Jpa; + +import org.junit.jupiter.api.Test; + +import static javax.persistence.CascadeType.ALL; + +/** + * @author Moritz Becker + */ +@TestForIssue(jiraKey = "HHH-13201") +@Jpa( + annotatedClasses = { + FetchNonRootRelativeElementCollectionAndAssociationTest.ProductNaturalId.class, + FetchNonRootRelativeElementCollectionAndAssociationTest.Product.class, + FetchNonRootRelativeElementCollectionAndAssociationTest.ProductDetail.class + } +) +public class FetchNonRootRelativeElementCollectionAndAssociationTest { + @Test + public void testJoinedSubclassUpdateWithCorrelation(EntityManagerFactoryScope scope) { + scope.inTransaction( + (entityManager) -> { + // DO NOT CHANGE this query: it used to trigger an error caused + // by the origin FromElement for the association fetch being resolved to the wrong FromElement due to the + // presence of an element collection join. + String u = "select prod from ProductNaturalId nat inner join nat.product prod " + + "left join fetch prod.productDetail " + + "left join fetch prod.normalizedPricesByUnit"; + Query query = entityManager.createQuery( u, Product.class ); + query.getResultList(); + } + ); + } + + @Entity(name = "ProductNaturalId") + public class ProductNaturalId { + @Id + private String naturalId; + @OneToOne(optional = false) + private Product product; + } + + @Entity(name = "Product") + public class Product { + @Id + private Long id; + @OneToOne(mappedBy = "product", cascade = ALL, fetch = FetchType.LAZY) + private ProductDetail productDetail; + @OneToOne(mappedBy = "product", cascade = ALL, fetch = FetchType.LAZY) + private ProductNaturalId naturalId; + @ElementCollection(fetch = FetchType.LAZY) + private Map normalizedPricesByUnit = new HashMap<>(); + } + + @Entity(name = "ProductDetail") + public class ProductDetail { + @Id + private Long id; + @OneToOne(optional = false) + @JoinColumn(name = "id") + @MapsId + private Product product; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/InsertWithSubSelectTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/InsertWithSubSelectTest.java new file mode 100644 index 0000000000..9d72511a89 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/InsertWithSubSelectTest.java @@ -0,0 +1,114 @@ +/* + * 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 javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.Test; + +/** + * @author bjoern.moritz + */ +@TestForIssue(jiraKey = "HHH-5274") +@DomainModel( + annotatedClasses = { + InsertWithSubSelectTest.A.class, + InsertWithSubSelectTest.B.class, + InsertWithSubSelectTest.C.class + } +) +@SessionFactory +public class InsertWithSubSelectTest { + @Test + public void testInsert(SessionFactoryScope scope) { + scope.inTransaction( + (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(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + final String qry = "select a.id " + + "from A a " + + "where exists (" + + " select 1 " + + " from B b " + + " where b.id = a.id" + + ")"; + session.createQuery( qry ).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; + } + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/QueryParametersValidationArrayTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/QueryParametersValidationArrayTest.java similarity index 84% rename from hibernate-core/src/test/java/org/hibernate/test/hql/QueryParametersValidationArrayTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/QueryParametersValidationArrayTest.java index 044936bd64..81ae52fad5 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/QueryParametersValidationArrayTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/QueryParametersValidationArrayTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.hql; +package org.hibernate.orm.test.query.hql; import java.sql.Array; import java.sql.CallableStatement; @@ -20,7 +20,6 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import org.hibernate.dialect.H2Dialect; -import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; import org.hibernate.query.NativeQuery; import org.hibernate.type.AbstractSingleColumnStandardBasicType; import org.hibernate.type.descriptor.ValueBinder; @@ -34,35 +33,32 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor; import org.hibernate.testing.RequiresDialect; import org.hibernate.testing.TestForIssue; -import org.junit.Test; - -import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; -import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; -import static org.junit.Assert.assertEquals; +import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; +import org.hibernate.testing.orm.junit.Jpa; +import org.junit.jupiter.api.Test; /** * @author Vlad Mihalcea */ @TestForIssue( jiraKey = "HHH-12292") @RequiresDialect(H2Dialect.class) -public class QueryParametersValidationArrayTest extends BaseEntityManagerFunctionalTestCase { - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] {Event.class}; - } - +@Jpa( + annotatedClasses = QueryParametersValidationArrayTest.Event.class +) +public class QueryParametersValidationArrayTest { @Test - public void setParameterWithWrongTypeShouldNotThrowIllegalArgumentException() { - doInJPA(this::entityManagerFactory, entityManager -> { - entityManager.createNativeQuery( - "select id " + - "from Event " + - "where readings = :readings" ) - .unwrap( NativeQuery.class ) - .setParameter( "readings", new String[]{null, "a"}, StringArrayType.INSTANCE ) - .getResultList(); - }); + public void setParameterWithWrongTypeShouldNotThrowIllegalArgumentException(EntityManagerFactoryScope scope) { + scope.inTransaction( + (entityManager) -> { + entityManager.createNativeQuery( + "select id " + + "from Event " + + "where readings = :readings" ) + .unwrap( NativeQuery.class ) + .setParameter( "readings", new String[]{null, "a"}, StringArrayType.INSTANCE ) + .getResultList(); + } + ); } @Entity(name = "Event") diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/QueryParametersValidationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/QueryParametersValidationTest.java new file mode 100644 index 0000000000..1804deead9 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/QueryParametersValidationTest.java @@ -0,0 +1,43 @@ +/* + * 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 javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.Test; + +/** + * @author Andrea Boriero + */ +@TestForIssue( jiraKey = "HHH-11397") +@DomainModel( annotatedClasses = QueryParametersValidationTest.TestEntity.class ) +@SessionFactory( exportSchema = false ) +public class QueryParametersValidationTest { + @Test + public void setParameterWithWrongTypeShouldNotThrowIllegalArgumentException(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> session.createQuery( "select e from TestEntity e where e.id = :id" ) + .setParameter( "id", 1 ) + ); + } + + @Entity(name = "TestEntity") + public class TestEntity { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + private String name; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/ToOneFetchAndJoinTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/ToOneFetchAndJoinTest.java new file mode 100644 index 0000000000..f65d7b6e4c --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/ToOneFetchAndJoinTest.java @@ -0,0 +1,176 @@ +/* + * 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 + */ + +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2015, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.orm.test.query.hql; + +import org.hibernate.Hibernate; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.hibernate.test.hql.fetchAndJoin.Entity1; +import org.hibernate.test.hql.fetchAndJoin.Entity2; +import org.hibernate.test.hql.fetchAndJoin.Entity3; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Gail Badner + */ +@DomainModel( + annotatedClasses = { + Entity1.class, + Entity2.class, + Entity3.class + } +) +@SessionFactory +public class ToOneFetchAndJoinTest { + + @Test + @TestForIssue( jiraKey = "HHH-9637") + public void testFetchJoinsWithImplicitJoinInRestriction(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + final String qry = + "select e1 " + + "from Entity1 e1 " + + " inner join fetch e1.entity2 e2 " + + " inner join fetch e2.entity3 " + + "where e1.entity2.value = 'entity2'"; + Entity1 e1Queryied = session.createQuery( qry, Entity1.class ).uniqueResult(); + assertEquals( "entity1", e1Queryied.getValue() ); + assertTrue( Hibernate.isInitialized( e1Queryied.getEntity2() ) ); + assertTrue( Hibernate.isInitialized( e1Queryied.getEntity2().getEntity3() ) ); + } + ); + } + + @Test + @TestForIssue( jiraKey = "HHH-9637") + public void testExplicitJoinBeforeFetchJoins(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + final String qry = + "select e1 " + + "from Entity1 e1 " + + " inner join e1.entity2 e1Restrict " + + " inner join fetch e1.entity2 e2" + + " inner join fetch e2.entity3 " + + "where e1Restrict.value = 'entity2'"; + Entity1 e1Queryied = session.createQuery( qry, Entity1.class ).uniqueResult(); + assertEquals( "entity1", e1Queryied.getValue() ); + assertTrue( Hibernate.isInitialized( e1Queryied.getEntity2() ) ); + assertTrue( Hibernate.isInitialized( e1Queryied.getEntity2().getEntity3() ) ); + } + ); + } + + @Test + @TestForIssue( jiraKey = "HHH-9637") + public void testExplicitJoinBetweenFetchJoins(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + final String qry = + "select e1 " + + "from Entity1 e1 " + + " inner join fetch e1.entity2 e2 " + + " inner join e1.entity2 e1Restrict " + + " inner join fetch e2.entity3 " + + "where e1Restrict.value = 'entity2'"; + Entity1 e1Queryied = session.createQuery( qry, Entity1.class ).uniqueResult(); + assertEquals( "entity1", e1Queryied.getValue() ); + assertTrue( Hibernate.isInitialized( e1Queryied.getEntity2() ) ); + assertTrue( Hibernate.isInitialized( e1Queryied.getEntity2().getEntity3() ) ); + } + ); + } + + @Test + @TestForIssue( jiraKey = "HHH-9637") + public void testExplicitJoinAfterFetchJoins(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + final String qry = + "select e1 " + + "from Entity1 e1 " + + " inner join fetch e1.entity2 e2 " + + " inner join fetch e2.entity3 " + + " inner join e1.entity2 e1Restrict " + + "where e1Restrict.value = 'entity2'"; + Entity1 e1Queryied = session.createQuery( qry, Entity1.class ).uniqueResult(); + assertEquals( "entity1", e1Queryied.getValue() ); + assertTrue( Hibernate.isInitialized( e1Queryied.getEntity2() ) ); + assertTrue( Hibernate.isInitialized( e1Queryied.getEntity2().getEntity3() ) ); + } + ); + } + + @BeforeEach + public void setupData(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + Entity1 e1 = new Entity1(); + e1.setValue( "entity1" ); + Entity2 e2 = new Entity2(); + e2.setValue( "entity2" ); + Entity3 e3 = new Entity3(); + e3.setValue( "entity3" ); + + e1.setEntity2( e2 ); + e2.setEntity3( e3 ); + + Entity2 e2a = new Entity2(); + e2a.setValue( "entity2a" ); + + session.persist( e3 ); + session.persist( e2 ); + session.persist( e1 ); + session.persist( e2a ); + } + ); + } + + @AfterEach + public void cleanupData(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + session.createQuery( "delete Entity1" ).executeUpdate(); + session.createQuery( "delete Entity2" ).executeUpdate(); + session.createQuery( "delete Entity3" ).executeUpdate(); + } + ); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/UpdateEntitiesWithPackageNamesStartingWithKeywordsTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/mutation/UpdateEntitiesWithPackageNamesStartingWithKeywordsTest.java similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/test/hql/UpdateEntitiesWithPackageNamesStartingWithKeywordsTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/mutation/UpdateEntitiesWithPackageNamesStartingWithKeywordsTest.java index 4fa57b8531..89e01d0942 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/UpdateEntitiesWithPackageNamesStartingWithKeywordsTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/mutation/UpdateEntitiesWithPackageNamesStartingWithKeywordsTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.hql; +package org.hibernate.orm.test.query.hql.mutation; import from.In; import in.from.Any; diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/UpdateEntityWithEmbeddedTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/mutation/UpdateEntityWithEmbeddedTest.java similarity index 67% rename from hibernate-core/src/test/java/org/hibernate/test/hql/UpdateEntityWithEmbeddedTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/mutation/UpdateEntityWithEmbeddedTest.java index e789f809d5..fa04645ab4 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/UpdateEntityWithEmbeddedTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/mutation/UpdateEntityWithEmbeddedTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.hql; +package org.hibernate.orm.test.query.hql.mutation; import javax.persistence.Embeddable; import javax.persistence.Embedded; @@ -12,26 +12,24 @@ import javax.persistence.Entity; import javax.persistence.Id; import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** * @author Andrea Boriero */ @TestForIssue(jiraKey = "HHH-14251") -public class UpdateEntityWithEmbeddedTest extends BaseCoreFunctionalTestCase { - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { Company.class }; - } - - @Before - public void setUp() { - inTransaction( - session -> { +@DomainModel( annotatedClasses = UpdateEntityWithEmbeddedTest.Company.class ) +@SessionFactory +public class UpdateEntityWithEmbeddedTest { + @BeforeEach + public void setUp(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { Logo logo = new Logo( "logo1", "png" ); Company company = new Company( 1l, logo ); session.save( company ); @@ -39,19 +37,19 @@ public class UpdateEntityWithEmbeddedTest extends BaseCoreFunctionalTestCase { ); } - @After - public void tearDown() { - inTransaction( - session -> { + @AfterEach + public void tearDown(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { session.createQuery( "delete from Company" ).executeUpdate(); } ); } @Test - public void testUpdate() { - inTransaction( - session -> { + public void testUpdate(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { Logo logo = new Logo( "logo2", "png" ); session.createQuery( "UPDATE Company c SET c.logo = :logo" ) .setParameter( "logo", logo ) @@ -61,9 +59,9 @@ public class UpdateEntityWithEmbeddedTest extends BaseCoreFunctionalTestCase { } @Test - public void testUpdate2() { - inTransaction( - session -> { + public void testUpdate2(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { session.createQuery( "UPDATE Company c SET c.logo.fileName = :filename, c.logo.fileExtension = :fileExtension" ) .setParameter( "filename", "logo2" ) diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/AggregateFunctionsWithSubSelectTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/AggregateFunctionsWithSubSelectTest.java deleted file mode 100644 index aee32965f2..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/AggregateFunctionsWithSubSelectTest.java +++ /dev/null @@ -1,230 +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 . - */ -package org.hibernate.test.hql; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.persistence.CollectionTable; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.MapKeyColumn; -import javax.persistence.OneToMany; -import javax.persistence.Tuple; - -import org.hibernate.dialect.H2Dialect; - -import org.hibernate.testing.RequiresDialect; -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.Test; - -import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; -import static org.junit.Assert.assertEquals; - -/** - * @author bjoern.moritz - */ -@TestForIssue(jiraKey = "HHH-9331") -@RequiresDialect(H2Dialect.class) -public class AggregateFunctionsWithSubSelectTest extends BaseCoreFunctionalTestCase { - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { - Document.class, - Person.class - }; - } - - @Override - protected void prepareTest() throws Exception { - doInHibernate( this::sessionFactory, session -> { - Document document = new Document(); - document.setId( 1 ); - - Person p1 = new Person(); - Person p2 = new Person(); - - p1.getLocalized().put(1, "p1.1"); - p1.getLocalized().put(2, "p1.2"); - p2.getLocalized().put(1, "p2.1"); - p2.getLocalized().put(2, "p2.2"); - - document.getContacts().put(1, p1); - document.getContacts().put(2, p2); - - session.persist(p1); - session.persist(p2); - session.persist(document); - } ); - } - - @Override - protected boolean isCleanupTestDataRequired() { - return true; - } - - @Test - public void testSum() { - - doInHibernate( this::sessionFactory, session -> { - List results = session.createQuery( - "SELECT " + - " d.id, " + - " SUM(" + - " (" + - " SELECT COUNT(localized) " + - " FROM Person p " + - " LEFT JOIN p.localized localized " + - " WHERE p.id = c.id" + - " )" + - " ) AS localizedCount " + - "FROM Document d " + - "LEFT JOIN d.contacts c " + - "GROUP BY d.id") - .getResultList(); - - assertEquals(1, results.size()); - Object[] tuple = (Object[]) results.get( 0 ); - assertEquals(1, tuple[0]); - } ); - } - - @Test - public void testMin() { - doInHibernate( this::sessionFactory, session -> { - List results = session.createQuery( - "SELECT " + - " d.id, " + - " MIN(" + - " (" + - " SELECT COUNT(localized) " + - " FROM Person p " + - " LEFT JOIN p.localized localized " + - " WHERE p.id = c.id" + - " )" + - " ) AS localizedCount " + - "FROM Document d " + - "LEFT JOIN d.contacts c " + - "GROUP BY d.id") - .getResultList(); - - assertEquals(1, results.size()); - Object[] tuple = (Object[]) results.get( 0 ); - assertEquals(1, tuple[0]); - } ); - } - - @Test - public void testMax() { - doInHibernate( this::sessionFactory, session -> { - List results = session.createQuery( - "SELECT " + - " d.id, " + - " MAX(" + - " (" + - " SELECT COUNT(localized) " + - " FROM Person p " + - " LEFT JOIN p.localized localized " + - " WHERE p.id = c.id" + - " )" + - " ) AS localizedCount " + - "FROM Document d " + - "LEFT JOIN d.contacts c " + - "GROUP BY d.id") - .getResultList(); - - assertEquals(1, results.size()); - Object[] tuple = (Object[]) results.get( 0 ); - assertEquals(1, tuple[0]); - } ); - } - - @Test - public void testAvg() { - doInHibernate( this::sessionFactory, session -> { - List results = session.createQuery( - "SELECT " + - " d.id, " + - " AVG(" + - " (" + - " SELECT COUNT(localized) " + - " FROM Person p " + - " LEFT JOIN p.localized localized " + - " WHERE p.id = c.id" + - " )" + - " ) AS localizedCount " + - "FROM Document d " + - "LEFT JOIN d.contacts c " + - "GROUP BY d.id") - .getResultList(); - - assertEquals(1, results.size()); - Object[] tuple = (Object[]) results.get( 0 ); - assertEquals(1, tuple[0]); - } ); - } - - @Entity(name = "Document") - public static class Document { - - private Integer id; - private Map contacts = new HashMap<>(); - - @Id - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - @OneToMany - @CollectionTable - @MapKeyColumn(name = "position") - public Map getContacts() { - return contacts; - } - - public void setContacts(Map contacts) { - this.contacts = contacts; - } - } - - - @Entity(name = "Person") - public static class Person { - - private Integer id; - - private Map localized = new HashMap<>(); - - @Id - @GeneratedValue - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - @ElementCollection - public Map getLocalized() { - return localized; - } - - public void setLocalized(Map localized) { - this.localized = localized; - } - } - -} diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/CollectionJoinSubQueryWithClauseTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/CollectionJoinSubQueryWithClauseTest.java new file mode 100644 index 0000000000..20cfe62291 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/hql/CollectionJoinSubQueryWithClauseTest.java @@ -0,0 +1,66 @@ +/* + * 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 java.util.List; + +import org.hibernate.cfg.AvailableSettings; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.hibernate.testing.orm.junit.Setting; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Implementation of WithClauseTest. + * + * @author Steve Ebersole + */ +@ServiceRegistry( + settings = @Setting( name = AvailableSettings.COLLECTION_JOIN_SUBQUERY, value = "false" ) +) +@DomainModel( + xmlMappings = { + "org/hibernate/test/hql/Animal.hbm.xml", + "org/hibernate/test/hql/SimpleEntityWithAssociation.hbm.xml", + } +) +@SessionFactory +public class CollectionJoinSubQueryWithClauseTest { + private final WithClauseTest.TestData data = new WithClauseTest.TestData(); + + @BeforeEach + public void createTestData(SessionFactoryScope scope) { + data.prepare( scope ); + } + + @AfterEach + public void dropTestData(SessionFactoryScope scope) { + data.cleanup( scope ); + } + + @Test + @TestForIssue(jiraKey = "HHH-11157") + public void testWithClauseAsNonSubqueryWithKey(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + // Since family has a join table, we will first left join all family members and then do the WITH clause on the target entity table join + // Normally this produces 2 results which is wrong and can only be circumvented by converting the join table and target entity table join to a subquery + final String qry = "from Human h left join h.family as f with key(f) like 'son1' where h.description = 'father'"; + List list = session.createQuery( qry ).list(); + assertEquals( "sub-query rewriting of join table was not disabled", 2, list.size() ); + } + ); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/CountExpressionTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/CountExpressionTest.java index 3c6df4c7cb..e921a8bf3d 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/CountExpressionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/hql/CountExpressionTest.java @@ -78,7 +78,7 @@ public class CountExpressionTest extends BaseCoreFunctionalTestCase { List results = session.createQuery( "SELECT " + " d.id, " + - " COUNT(DISTINCT CONCAT(CAST(KEY(l) AS java.lang.String), 'test')) " + + " COUNT(DISTINCT CONCAT(CAST(KEY(l) AS String), 'test')) " + "FROM Document d " + "LEFT JOIN d.contacts c " + "LEFT JOIN c.localized l " + diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/FetchNonRootRelativeElementCollectionAndAssociationTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/FetchNonRootRelativeElementCollectionAndAssociationTest.java deleted file mode 100644 index cf9e99cea7..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/FetchNonRootRelativeElementCollectionAndAssociationTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.hibernate.test.hql; - -import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; - -import org.hibernate.testing.TestForIssue; -import org.junit.Test; - -import javax.persistence.*; - -import java.util.HashMap; -import java.util.Map; - -import static javax.persistence.CascadeType.ALL; -import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; - -/** - * @author Moritz Becker - */ -@TestForIssue(jiraKey = "HHH-13201") -public class FetchNonRootRelativeElementCollectionAndAssociationTest extends BaseEntityManagerFunctionalTestCase { - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { ProductNaturalId.class, Product.class, ProductDetail.class }; - } - - @Test - public void testJoinedSubclassUpdateWithCorrelation() { - doInJPA( this::entityManagerFactory, entityManager -> { - // DO NOT CHANGE this query: it used to trigger an error caused - // by the origin FromElement for the association fetch being resolved to the wrong FromElement due to the - // presence of an element collection join. - String u = "select prod from ProductNaturalId nat inner join nat.product prod " + - "left join fetch prod.productDetail " + - "left join fetch prod.normalizedPricesByUnit"; - Query query = entityManager.createQuery( u, Product.class ); - query.getResultList(); - } ); - } - - @Entity(name = "ProductNaturalId") - public class ProductNaturalId { - @Id - private String naturalId; - @OneToOne(optional = false) - private Product product; - } - - @Entity(name = "Product") - public class Product { - @Id - private Long id; - @OneToOne(mappedBy = "product", cascade = ALL, fetch = FetchType.LAZY) - private ProductDetail productDetail; - @OneToOne(mappedBy = "product", cascade = ALL, fetch = FetchType.LAZY) - private ProductNaturalId naturalId; - @ElementCollection(fetch = FetchType.LAZY) - private Map normalizedPricesByUnit = new HashMap<>(); - } - - @Entity(name = "ProductDetail") - public class ProductDetail { - @Id - private Long id; - @OneToOne(optional = false) - @JoinColumn(name = "id") - @MapsId - private Product product; - } -} 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 deleted file mode 100644 index d44f41b63d..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/InsertWithSubSelectTest.java +++ /dev/null @@ -1,114 +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 . - */ -package org.hibernate.test.hql; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; - -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.Test; - -import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; - -/** - * @author bjoern.moritz - */ -@TestForIssue(jiraKey = "HHH-5274") -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; - } - } - -} diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/QueryParametersValidationTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/QueryParametersValidationTest.java deleted file mode 100644 index e325d43c9d..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/QueryParametersValidationTest.java +++ /dev/null @@ -1,45 +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 . - */ -package org.hibernate.test.hql; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; - -import org.hibernate.Session; - -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.Test; - -/** - * @author Andrea Boriero - */ -@TestForIssue( jiraKey = "HHH-11397") -public class QueryParametersValidationTest extends BaseCoreFunctionalTestCase { - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] {TestEntity.class}; - } - - @Test - public void setParameterWithWrongTypeShouldNotThrowIllegalArgumentException() { - try (Session session = openSession()) { - session.createQuery( "select e from TestEntity e where e.id = :id" ).setParameter( "id", 1 ); - } - } - - @Entity(name = "TestEntity") - public class TestEntity { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - } -} diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/ScrollableCollectionFetchingTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/ScrollableCollectionFetchingTest.java index 1d84e4b0c9..a15075807d 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/ScrollableCollectionFetchingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/hql/ScrollableCollectionFetchingTest.java @@ -38,7 +38,6 @@ import static org.junit.Assert.fail; * @author Steve Ebersole */ @FailureExpected( jiraKey = "none", message = "Support for scrolling collection fetches not yet implemented" ) -@NotImplementedYet public class ScrollableCollectionFetchingTest extends BaseCoreFunctionalTestCase { public String[] getMappings() { return new String[] { "hql/Animal.hbm.xml" }; diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/WithClauseTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/WithClauseTest.java index cf05b80212..c567b9c715 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/WithClauseTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/hql/WithClauseTest.java @@ -11,17 +11,18 @@ import java.util.HashMap; import java.util.List; import org.hibernate.HibernateException; -import org.hibernate.query.Query; import org.hibernate.QueryException; -import org.hibernate.Session; -import org.hibernate.Transaction; -import org.hibernate.cfg.AvailableSettings; import org.hibernate.dialect.DerbyDialect; +import org.hibernate.query.Query; import org.hibernate.testing.SkipForDialect; import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.Test; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; import static org.junit.Assert.assertEquals; @@ -34,312 +35,256 @@ import static org.junit.Assert.fail; * * @author Steve Ebersole */ -public class WithClauseTest extends BaseCoreFunctionalTestCase { - public String[] getMappings() { - return new String[] { "hql/Animal.hbm.xml", "hql/SimpleEntityWithAssociation.hbm.xml" }; +@DomainModel( + xmlMappings = { + "org/hibernate/test/hql/Animal.hbm.xml", + "org/hibernate/test/hql/SimpleEntityWithAssociation.hbm.xml", + } +) +@SessionFactory +public class WithClauseTest { + private final TestData data = new TestData(); + + @BeforeEach + public void createTestData(SessionFactoryScope scope) { + data.prepare( scope ); + } + + @AfterEach + public void dropTestData(SessionFactoryScope scope) { + data.cleanup( scope ); } @Test - public void testWithClauseFailsWithFetch() { - TestData data = new TestData(); - data.prepare(); - - Session s = openSession(); - Transaction txn = s.beginTransaction(); - - try { - s.createQuery( "from Animal a inner join fetch a.offspring as o with o.bodyWeight = :someLimit" ) - .setParameter( "someLimit", 1 ) - .list(); - fail( "ad-hoc on clause allowed with fetched association" ); - } - catch (IllegalArgumentException e) { - assertTyping( QueryException.class, e.getCause() ); - } - catch ( HibernateException e ) { - // the expected response... - } - - txn.commit(); - s.close(); - - data.cleanup(); + public void testWithClauseFailsWithFetch(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + try { + session.createQuery( "from Animal a inner join fetch a.offspring as o with o.bodyWeight = :someLimit" ) + .setParameter( "someLimit", 1 ) + .list(); + fail( "ad-hoc on clause allowed with fetched association" ); + } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } + catch ( HibernateException e ) { + // the expected response... + } + } + ); } @Test - public void testWithClause() { - TestData data = new TestData(); - data.prepare(); + public void testWithClause(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + // one-to-many + List list = session.createQuery( "from Human h inner join h.offspring as o with o.bodyWeight < :someLimit" ) + .setParameter( "someLimit", 1 ) + .list(); + assertTrue( "ad-hoc on did not take effect", list.isEmpty() ); - Session s = openSession(); - Transaction txn = s.beginTransaction(); + // many-to-one + list = session.createQuery( "from Animal a inner join a.mother as m with m.bodyWeight < :someLimit" ) + .setParameter( "someLimit", 1 ) + .list(); + assertTrue( "ad-hoc on did not take effect", list.isEmpty() ); - // one-to-many - List list = s.createQuery( "from Human h inner join h.offspring as o with o.bodyWeight < :someLimit" ) - .setParameter( "someLimit", 1 ) - .list(); - assertTrue( "ad-hoc on did not take effect", list.isEmpty() ); + list = session.createQuery( "from Human h inner join h.friends f with f.bodyWeight < :someLimit" ) + .setParameter( "someLimit", 25 ) + .list(); + assertTrue( "ad-hoc on did take effect", !list.isEmpty() ); - // many-to-one - list = s.createQuery( "from Animal a inner join a.mother as m with m.bodyWeight < :someLimit" ) - .setParameter( "someLimit", 1 ) - .list(); - assertTrue( "ad-hoc on did not take effect", list.isEmpty() ); + // many-to-many + list = session.createQuery( "from Human h inner join h.friends as f with f.nickName like 'bubba'" ) + .list(); + assertTrue( "ad-hoc on did not take effect", list.isEmpty() ); - list = s.createQuery( "from Human h inner join h.friends f with f.bodyWeight < :someLimit" ) - .setParameter( "someLimit", 25 ) - .list(); - assertTrue( "ad-hoc on did take effect", !list.isEmpty() ); + // http://opensource.atlassian.com/projects/hibernate/browse/HHH-1930 + list = session.createQuery( "from Human h inner join h.nickNames as nicknames with nicknames = 'abc'" ) + .list(); + assertTrue( "ad-hoc on did not take effect", list.isEmpty() ); - // many-to-many - list = s.createQuery( "from Human h inner join h.friends as f with f.nickName like 'bubba'" ) - .list(); - assertTrue( "ad-hoc on did not take effect", list.isEmpty() ); - - // http://opensource.atlassian.com/projects/hibernate/browse/HHH-1930 - list = s.createQuery( "from Human h inner join h.nickNames as nicknames with nicknames = 'abc'" ) - .list(); - assertTrue( "ad-hoc on did not take effect", list.isEmpty() ); - - list = s.createQuery( "from Human h inner join h.offspring o with o.mother.father = :cousin" ) - .setParameter( "cousin", s.load( Human.class, Long.valueOf( "123" ) ) ) - .list(); - assertTrue( "ad-hoc did take effect", list.isEmpty() ); - - txn.commit(); - s.close(); - - data.cleanup(); + list = session.createQuery( "from Human h inner join h.offspring o with o.mother.father = :cousin" ) + .setParameter( "cousin", session.load( Human.class, Long.valueOf( "123" ) ) ) + .list(); + assertTrue( "ad-hoc did take effect", list.isEmpty() ); + } + ); } @Test @TestForIssue(jiraKey = "HHH-2772") - public void testWithJoinRHS() { - Session s = openSession(); - s.beginTransaction(); + public void testWithJoinRHS(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + SimpleEntityWithAssociation entity1 = new SimpleEntityWithAssociation(); + entity1.setName( "entity1" ); + SimpleEntityWithAssociation entity2 = new SimpleEntityWithAssociation(); + entity2.setName( "entity2" ); - SimpleEntityWithAssociation entity1 = new SimpleEntityWithAssociation(); - entity1.setName( "entity1" ); - SimpleEntityWithAssociation entity2 = new SimpleEntityWithAssociation(); - entity2.setName( "entity2" ); - - SimpleAssociatedEntity associatedEntity1 = new SimpleAssociatedEntity(); - associatedEntity1.setName( "associatedEntity1" ); - SimpleAssociatedEntity associatedEntity2 = new SimpleAssociatedEntity(); - associatedEntity2.setName( "associatedEntity2" ); - - entity1.addAssociation( associatedEntity1 ); - entity2.addAssociation( associatedEntity2 ); - - s.persist( entity1 ); - s.persist( entity2 ); - - s.getTransaction().commit(); - s.clear(); - - s.beginTransaction(); - - Query query = s.createQuery( "select a from SimpleEntityWithAssociation as e INNER JOIN e.associatedEntities as a WITH e.name=?1" ); - query.setParameter( 1, "entity1" ); - List list = query.list(); - assertEquals( list.size(), 1 ); - - SimpleAssociatedEntity associatedEntity = (SimpleAssociatedEntity) query.list().get( 0 ); - assertNotNull( associatedEntity ); - assertEquals( associatedEntity.getName(), "associatedEntity1" ); - assertEquals( associatedEntity.getOwner().getName(), "entity1" ); - - s.getTransaction().commit(); - s.close(); + SimpleAssociatedEntity associatedEntity1 = new SimpleAssociatedEntity(); + associatedEntity1.setName( "associatedEntity1" ); + SimpleAssociatedEntity associatedEntity2 = new SimpleAssociatedEntity(); + associatedEntity2.setName( "associatedEntity2" ); + + entity1.addAssociation( associatedEntity1 ); + entity2.addAssociation( associatedEntity2 ); + + session.persist( entity1 ); + session.persist( entity2 ); + } + ); + + scope.inTransaction( + (session) -> { + Query query = session.createQuery( "select a from SimpleEntityWithAssociation as e INNER JOIN e.associatedEntities as a WITH e.name=?1" ); + query.setParameter( 1, "entity1" ); + List list = query.list(); + assertEquals( list.size(), 1 ); + + SimpleAssociatedEntity associatedEntity = (SimpleAssociatedEntity) query.list().get( 0 ); + assertNotNull( associatedEntity ); + assertEquals( associatedEntity.getName(), "associatedEntity1" ); + assertEquals( associatedEntity.getOwner().getName(), "entity1" ); + } + ); } @Test @TestForIssue(jiraKey = "HHH-9329") - public void testWithClauseAsSubquery() { - TestData data = new TestData(); - data.prepare(); - - Session s = openSession(); - Transaction txn = s.beginTransaction(); - - // Since friends has a join table, we will first left join all friends and then do the WITH clause on the target entity table join - // Normally this produces 2 results which is wrong and can only be circumvented by converting the join table and target entity table join to a subquery - List list = s.createQuery( "from Human h left join h.friends as f with f.nickName like 'bubba' where h.description = 'father'" ) - .list(); - assertEquals( "subquery rewriting of join table did not take effect", 1, list.size() ); - - txn.commit(); - s.close(); - - data.cleanup(); + public void testWithClauseAsSubquery(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + // Since friends has a join table, we will first left join all friends and then do the WITH clause on the target entity table join + // Normally this produces 2 results which is wrong and can only be circumvented by converting the join table and target entity table join to a subquery + List list = session.createQuery( "from Human h left join h.friends as f with f.nickName like 'bubba' where h.description = 'father'" ) + .list(); + assertEquals( "subquery rewriting of join table did not take effect", 1, list.size() ); + } + ); } @Test @TestForIssue(jiraKey = "HHH-11230") - public void testWithClauseAsSubqueryWithEqualOperator() { - TestData data = new TestData(); - data.prepare(); - - Session s = openSession(); - Transaction txn = s.beginTransaction(); - - // Like testWithClauseAsSubquery but uses equal operator since it render differently in SQL - List list = s.createQuery( "from Human h left join h.friends as f with f.nickName = 'bubba' where h.description = 'father'" ) - .list(); - assertEquals( "subquery rewriting of join table did not take effect", 1, list.size() ); - - txn.commit(); - s.close(); - - data.cleanup(); + public void testWithClauseAsSubqueryWithEqualOperator(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + // Like testWithClauseAsSubquery but uses equal operator since it render differently in SQL + List list = session.createQuery( "from Human h left join h.friends as f with f.nickName = 'bubba' where h.description = 'father'" ) + .list(); + assertEquals( "subquery rewriting of join table did not take effect", 1, list.size() ); + } + ); } @Test @TestForIssue(jiraKey = "HHH-9329") - public void testWithClauseAsSubqueryWithKey() { - TestData data = new TestData(); - data.prepare(); - - Session s = openSession(); - Transaction txn = s.beginTransaction(); - - // Since family has a join table, we will first left join all family members and then do the WITH clause on the target entity table join - // Normally this produces 2 results which is wrong and can only be circumvented by converting the join table and target entity table join to a subquery - List list = s.createQuery( "from Human h left join h.family as f with key(f) like 'son1' where h.description = 'father'" ) - .list(); - assertEquals( "subquery rewriting of join table did not take effect", 1, list.size() ); - - txn.commit(); - s.close(); - - data.cleanup(); - } - - @Test - @TestForIssue(jiraKey = "HHH-11157") - public void testWithClauseAsNonSubqueryWithKey() { - rebuildSessionFactory( c -> c.setProperty( AvailableSettings.COLLECTION_JOIN_SUBQUERY, "false" ) ); - - try { - TestData data = new TestData(); - data.prepare(); - - Session s = openSession(); - Transaction txn = s.beginTransaction(); - - // Since family has a join table, we will first left join all family members and then do the WITH clause on the target entity table join - // Normally this produces 2 results which is wrong and can only be circumvented by converting the join table and target entity table join to a subquery - List list = s.createQuery( "from Human h left join h.family as f with key(f) like 'son1' where h.description = 'father'" ) - .list(); - assertEquals( "subquery rewriting of join table was not disabled", 2, list.size() ); - - txn.commit(); - s.close(); - - data.cleanup(); - } finally { - // Rebuild to reset the properties - rebuildSessionFactory(); - } + public void testWithClauseAsSubqueryWithKey(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + // Since family has a join table, we will first left join all family members and then do the WITH clause on the target entity table join + // Normally this produces 2 results which is wrong and can only be circumvented by converting the join table and target entity table join to a subquery + List list = session.createQuery( "from Human h left join h.family as f with key(f) like 'son1' where h.description = 'father'" ) + .list(); + assertEquals( "subquery rewriting of join table did not take effect", 1, list.size() ); + } + ); } @Test @TestForIssue(jiraKey = "HHH-11401") @SkipForDialect(value = DerbyDialect.class,comment = "Derby does not support cast from INTEGER to VARCHAR") - public void testWithClauseAsSubqueryWithKeyAndOtherJoinReference() { - TestData data = new TestData(); - data.prepare(); - - Session s = openSession(); - Transaction txn = s.beginTransaction(); - - // Just a stupid example that makes use of a column that isn't from the collection table or the target entity table - List list = s.createQuery( "from Human h join h.friends as friend left join h.family as f with key(f) = concat('son', cast(friend.intValue as string)) where h.description = 'father'" ) - .list(); - assertEquals( "subquery rewriting of join table did not take effect", 2, list.size() ); - - txn.commit(); - s.close(); - - data.cleanup(); + public void testWithClauseAsSubqueryWithKeyAndOtherJoinReference(SessionFactoryScope scope) { + scope.inTransaction( + (s) -> { + // Just a stupid example that makes use of a column that isn't from the collection table or the target entity table + List list = s.createQuery( "from Human h join h.friends as friend left join h.family as f with key(f) = concat('son', cast(friend.intValue as string)) where h.description = 'father'" ) + .list(); + assertEquals( "subquery rewriting of join table did not take effect", 2, list.size() ); + } + ); } - private class TestData { - public void prepare() { - Session session = openSession(); - Transaction txn = session.beginTransaction(); + static class TestData { + public void prepare(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + Human mother = new Human(); + mother.setBodyWeight( 10 ); + mother.setDescription( "mother" ); - Human mother = new Human(); - mother.setBodyWeight( 10 ); - mother.setDescription( "mother" ); + Human father = new Human(); + father.setBodyWeight( 15 ); + father.setDescription( "father" ); - Human father = new Human(); - father.setBodyWeight( 15 ); - father.setDescription( "father" ); + Human child1 = new Human(); + child1.setBodyWeight( 5 ); + child1.setDescription( "child1" ); - Human child1 = new Human(); - child1.setBodyWeight( 5 ); - child1.setDescription( "child1" ); + Human child2 = new Human(); + child2.setBodyWeight( 6 ); + child2.setDescription( "child2" ); - Human child2 = new Human(); - child2.setBodyWeight( 6 ); - child2.setDescription( "child2" ); + Human friend = new Human(); + friend.setBodyWeight( 20 ); + friend.setDescription( "friend" ); + friend.setIntValue( 1 ); - Human friend = new Human(); - friend.setBodyWeight( 20 ); - friend.setDescription( "friend" ); - friend.setIntValue( 1 ); + Human friend2 = new Human(); + friend2.setBodyWeight( 20 ); + friend2.setDescription( "friend2" ); + friend.setIntValue( 2 ); - Human friend2 = new Human(); - friend2.setBodyWeight( 20 ); - friend2.setDescription( "friend2" ); - friend.setIntValue( 2 ); + child1.setMother( mother ); + child1.setFather( father ); + mother.addOffspring( child1 ); + father.addOffspring( child1 ); - child1.setMother( mother ); - child1.setFather( father ); - mother.addOffspring( child1 ); - father.addOffspring( child1 ); + child2.setMother( mother ); + child2.setFather( father ); + mother.addOffspring( child2 ); + father.addOffspring( child2 ); - child2.setMother( mother ); - child2.setFather( father ); - mother.addOffspring( child2 ); - father.addOffspring( child2 ); + father.setFriends( new ArrayList() ); + father.getFriends().add( friend ); + father.getFriends().add( friend2 ); - father.setFriends( new ArrayList() ); - father.getFriends().add( friend ); - father.getFriends().add( friend2 ); + session.save( mother ); + session.save( father ); + session.save( child1 ); + session.save( child2 ); + session.save( friend ); + session.save( friend2 ); - session.save( mother ); - session.save( father ); - session.save( child1 ); - session.save( child2 ); - session.save( friend ); - session.save( friend2 ); - - father.setFamily( new HashMap() ); - father.getFamily().put( "son1", child1 ); - father.getFamily().put( "son2", child2 ); - - txn.commit(); - session.close(); + father.setFamily( new HashMap() ); + father.getFamily().put( "son1", child1 ); + father.getFamily().put( "son2", child2 ); + } + ); } - public void cleanup() { - Session session = openSession(); - Transaction txn = session.beginTransaction(); - Human father = (Human) session.createQuery( "from Human where description = 'father'" ).uniqueResult(); - father.getFriends().clear(); - father.getFamily().clear(); - session.flush(); - session.delete( session.createQuery( "from Human where description = 'friend2'" ).uniqueResult() ); - session.delete( session.createQuery( "from Human where description = 'friend'" ).uniqueResult() ); - session.delete( session.createQuery( "from Human where description = 'child1'" ).uniqueResult() ); - session.delete( session.createQuery( "from Human where description = 'child2'" ).uniqueResult() ); - session.delete( session.createQuery( "from Human where description = 'mother'" ).uniqueResult() ); - session.delete( father ); - session.createQuery( "delete Animal" ).executeUpdate(); - txn.commit(); - session.close(); + public void cleanup(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + Human father = (Human) session.createQuery( "from Human where description = 'father'" ).uniqueResult(); + if ( father != null ) { + father.getFriends().clear(); + father.getFamily().clear(); + session.flush(); + } + session.delete( session.createQuery( "from Human where description = 'friend2'" ).uniqueResult() ); + session.delete( session.createQuery( "from Human where description = 'friend'" ).uniqueResult() ); + session.delete( session.createQuery( "from Human where description = 'child1'" ).uniqueResult() ); + session.delete( session.createQuery( "from Human where description = 'child2'" ).uniqueResult() ); + session.delete( session.createQuery( "from Human where description = 'mother'" ).uniqueResult() ); + session.delete( father ); + session.createQuery( "delete Animal" ).executeUpdate(); + session.createQuery( "delete SimpleEntityWithAssociation" ).executeUpdate(); + session.createQuery( "delete SimpleAssociatedEntity" ).executeUpdate(); + } + ); } } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/fetchAndJoin/ToOneFetchAndJoinTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/fetchAndJoin/ToOneFetchAndJoinTest.java deleted file mode 100644 index 4a6f7cbd59..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/fetchAndJoin/ToOneFetchAndJoinTest.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2015, Red Hat Inc. or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Inc. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - */ -package org.hibernate.test.hql.fetchAndJoin; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.hibernate.Hibernate; -import org.hibernate.Session; -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * @author Gail Badner - */ -public class ToOneFetchAndJoinTest extends BaseCoreFunctionalTestCase { - - @Before - public void setupData() { - Entity1 e1 = new Entity1(); - e1.setValue( "entity1" ); - Entity2 e2 = new Entity2(); - e2.setValue( "entity2" ); - Entity3 e3 = new Entity3(); - e3.setValue( "entity3" ); - - e1.setEntity2( e2 ); - e2.setEntity3( e3 ); - - Entity2 e2a = new Entity2(); - e2a.setValue( "entity2a" ); - - Session s = openSession(); - s.getTransaction().begin(); - s.persist( e3 ); - s.persist( e2 ); - s.persist( e1 ); - s.persist( e2a ); - s.getTransaction().commit(); - s.close(); - } - - @After - public void cleanupData() { - Session s = openSession(); - s.getTransaction().begin(); - s.createQuery( "delete Entity1" ).executeUpdate(); - s.createQuery( "delete Entity2" ).executeUpdate(); - s.createQuery( "delete Entity3" ).executeUpdate(); - s.getTransaction().commit(); - s.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-9637") - public void testFetchJoinsWithImplicitJoinInRestriction() { - - Session s = openSession(); - s.getTransaction().begin(); - - Entity1 e1Queryied = - (Entity1) s.createQuery( - "select e1 from Entity1 e1 inner join fetch e1.entity2 e2 inner join fetch e2.entity3 where e1.entity2.value = 'entity2'" ) - .uniqueResult(); - assertEquals( "entity1", e1Queryied.getValue() ); - assertTrue( Hibernate.isInitialized( e1Queryied.getEntity2() ) ); - assertTrue( Hibernate.isInitialized( e1Queryied.getEntity2().getEntity3() ) ); - s.getTransaction().commit(); - s.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-9637") - public void testExplicitJoinBeforeFetchJoins() { - - Session s = openSession(); - s.getTransaction().begin(); - - Entity1 e1Queryied = - (Entity1) s.createQuery( - "select e1 from Entity1 e1 inner join e1.entity2 e1Restrict inner join fetch e1.entity2 e2 inner join fetch e2.entity3 where e1Restrict.value = 'entity2'" ) - .uniqueResult(); - assertEquals( "entity1", e1Queryied.getValue() ); - assertTrue( Hibernate.isInitialized( e1Queryied.getEntity2() ) ); - assertTrue( Hibernate.isInitialized( e1Queryied.getEntity2().getEntity3() ) ); - s.getTransaction().commit(); - s.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-9637") - public void testExplicitJoinBetweenFetchJoins() { - - Session s = openSession(); - s.getTransaction().begin(); - - Entity1 e1Queryied = - (Entity1) s.createQuery( - "select e1 from Entity1 e1 inner join fetch e1.entity2 e2 inner join e1.entity2 e1Restrict inner join fetch e2.entity3 where e1Restrict.value = 'entity2'" ) - .uniqueResult(); - assertEquals( "entity1", e1Queryied.getValue() ); - assertTrue( Hibernate.isInitialized( e1Queryied.getEntity2() ) ); - assertTrue( Hibernate.isInitialized( e1Queryied.getEntity2().getEntity3() ) ); - s.getTransaction().commit(); - s.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-9637") - public void testExplicitJoinAfterFetchJoins() { - - Session s = openSession(); - s.getTransaction().begin(); - - Entity1 e1Queryied = - (Entity1) s.createQuery( - "select e1 from Entity1 e1 inner join fetch e1.entity2 e2 inner join fetch e2.entity3 inner join e1.entity2 e1Restrict where e1Restrict.value = 'entity2'" ) - .uniqueResult(); - assertEquals( "entity1", e1Queryied.getValue() ); - assertTrue( Hibernate.isInitialized( e1Queryied.getEntity2() ) ); - assertTrue( Hibernate.isInitialized( e1Queryied.getEntity2().getEntity3() ) ); - s.getTransaction().commit(); - s.close(); - } - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[]{ - Entity1.class, - Entity2.class, - Entity3.class - }; - } -}