re-enable tests

re-organize some tests
fixed edge case for implicit basic type resolution
This commit is contained in:
Steve Ebersole 2021-03-30 08:47:16 -05:00
parent fcd7a6f356
commit a692061ae1
19 changed files with 1031 additions and 972 deletions

View File

@ -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

View File

@ -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,

View File

@ -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<Integer, Person> contacts = new HashMap<>();
@Id
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@OneToMany
@CollectionTable
@MapKeyColumn(name = "position")
public Map<Integer, Person> getContacts() {
return contacts;
}
public void setContacts(Map<Integer, Person> contacts) {
this.contacts = contacts;
}
}
@Entity(name = "Person")
public static class Person {
private Integer id;
private Map<Integer, String> localized = new HashMap<>();
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@ElementCollection
public Map<Integer, String> getLocalized() {
return localized;
}
public void setLocalized(Map<Integer, String> localized) {
this.localized = localized;
}
}
}

View File

@ -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<String, String> normalizedPricesByUnit = new HashMap<>();
}
@Entity(name = "ProductDetail")
public class ProductDetail {
@Id
private Long id;
@OneToOne(optional = false)
@JoinColumn(name = "id")
@MapsId
private Product product;
}
}

View File

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

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
* 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")

View File

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

View File

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

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
* 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;

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
* 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" )

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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<Integer, Person> contacts = new HashMap<>();
@Id
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@OneToMany
@CollectionTable
@MapKeyColumn(name = "position")
public Map<Integer, Person> getContacts() {
return contacts;
}
public void setContacts(Map<Integer, Person> contacts) {
this.contacts = contacts;
}
}
@Entity(name = "Person")
public static class Person {
private Integer id;
private Map<Integer, String> localized = new HashMap<>();
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@ElementCollection
public Map<Integer, String> getLocalized() {
return localized;
}
public void setLocalized(Map<Integer, String> localized) {
this.localized = localized;
}
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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() );
}
);
}
}

View File

@ -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 " +

View File

@ -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<String, String> normalizedPricesByUnit = new HashMap<>();
}
@Entity(name = "ProductDetail")
public class ProductDetail {
@Id
private Long id;
@OneToOne(optional = false)
@JoinColumn(name = "id")
@MapsId
private Product product;
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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;
}
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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;
}
}

View File

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

View File

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

View File

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