diff --git a/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/TreatJoinTest.java b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/TreatJoinTest.java new file mode 100644 index 0000000000..3566728db2 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/TreatJoinTest.java @@ -0,0 +1,175 @@ +/* + * 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.jpa.test.criteria; + +import javax.persistence.Entity; +import javax.persistence.EntityManager; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Join; +import javax.persistence.criteria.Root; +import java.util.List; + +import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; + +import org.junit.Test; + +import org.hibernate.testing.TestForIssue; + +/** + * @author Andrea Boriero + */ +@TestForIssue(jiraKey = "HHH-10844") +public class TreatJoinTest extends BaseEntityManagerFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] {Item.class, Price.class, Book.class, Bid.class, Author.class, Car.class, Person.class}; + } + + @Test + public void testTreatJoin() { + EntityManager em = createEntityManager(); + try { + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery query = cb.createQuery( Bid.class ); + Root bid = query.from( Bid.class ); + + Join book = cb.treat( bid.join( "item" ), Book.class ); + query.select( book.get( "title" ) ); + + em.createQuery( query ).getResultList(); + } + finally { + em.close(); + } + } + + @Test + public void testTreatJoin2() { + EntityManager em = createEntityManager(); + try { + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery query = cb.createQuery( Bid.class ); + Root bid = query.from( Bid.class ); + + cb.treat( bid.join( "item" ), Book.class ); + cb.treat( bid.join( "item" ), Car.class ); + + query.select( bid ); + + em.createQuery( query ).getResultList(); + } + finally { + em.close(); + } + } + + @Test + public void testJoinMethodOnATreatedJoin() { + EntityManager em = createEntityManager(); + try { + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery query = cb.createQuery( Bid.class ); + Root bid = query.from( Bid.class ); + + final Join item = bid.join( "item" ); + final Join price = item.join( "price" ); + Join book = cb.treat( item, Book.class ); + + Join owner = book.join( "author" ); + query.select( owner.get( "name" ) ); + + query.where( cb.equal( price.get("amount"), 1L ) ); + + em.createQuery( query ).getResultList(); + + } + finally { + em.close(); + } + } + + @Entity + public static class Item { + @Id + @GeneratedValue + private Long id; + + @ManyToOne + private Price price; + + } + + @Entity + public static class Price{ + @Id + long id; + + int amount; + + String currency; + } + + @Entity(name = "Book") + @Table(name="BOOK") + public static class Book extends Item { + @ManyToOne + private Author author; + + String title; + } + + @Entity(name = "Car") + @Table(name="CAR") + public static class Car extends Item { + @OneToMany + private List owners; + + String color; + } + + @Entity(name = "Bid") + @Table(name = "BID") + public static class Bid { + @Id + @GeneratedValue + private Long id; + + @ManyToOne + private Item item; + } + + @Entity(name = "Author") + @Table(name = "AUTHOR") + public static class Author { + @Id + @GeneratedValue + private Long id; + + private String name; + } + + @Entity(name = "Person") + @Table(name = "PERSON") + public static class Person { + @Id + @GeneratedValue + private Long id; + + private String name; + } + + +} diff --git a/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/TreatListJoinTest.java b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/TreatListJoinTest.java new file mode 100644 index 0000000000..6a67266268 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/TreatListJoinTest.java @@ -0,0 +1,177 @@ +/* + * 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.jpa.test.criteria; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.EntityManager; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.MappedSuperclass; +import javax.persistence.OneToMany; +import javax.persistence.Tuple; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.JoinType; +import javax.persistence.criteria.ListJoin; +import javax.persistence.criteria.Root; +import javax.persistence.criteria.Selection; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; + +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +/** + * @author Andrea Boriero + */ +public class TreatListJoinTest extends BaseEntityManagerFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] {TestEntity.class, EntityA.class, EntityB.class}; + } + + @Before + public void setUp() { + EntityManager em = createEntityManager(); + try { + em.getTransaction().begin(); + + for ( int i = 0; i < 5; i++ ) { + TestEntity e = new TestEntity(); + EntityA eA = new EntityA(); + eA.setParent( e ); + eA.valueA = "a_" + i; + + em.persist( e ); + } + for ( int i = 0; i < 5; i++ ) { + TestEntity e = new TestEntity(); + + EntityB eB = new EntityB(); + eB.valueB = "b_" + i; + eB.setParent( e ); + + em.persist( e ); + } + + em.getTransaction().commit(); + } + catch (Exception e) { + if ( em.getTransaction().isActive() ) { + em.getTransaction().rollback(); + } + throw e; + } + finally { + em.close(); + } + } + + @Test + public void testTreatJoin() { + EntityManager em = createEntityManager(); + try { + final CriteriaBuilder cb = em.getCriteriaBuilder(); + + final CriteriaQuery query = cb.createTupleQuery(); + final Root testEntity = query.from( TestEntity.class ); + + final List> selections = new LinkedList(); + selections.add( testEntity.get( "id" ) ); + + final ListJoin entities = testEntity.joinList( + "entities", + JoinType.LEFT + ); + entities.on( cb.equal( entities.get( "entityType" ), EntityA.class.getName() ) ); + + final ListJoin joinEntityA = cb.treat( + entities, + EntityA.class + ); + selections.add( joinEntityA.get( "id" ) ); + selections.add( joinEntityA.get( "valueA" ) ); + + final ListJoin entitiesB = testEntity.joinList( + "entities", + JoinType.LEFT + ); + entitiesB.on( cb.equal( entitiesB.get( "entityType" ), EntityB.class.getName() ) ); + final ListJoin joinEntityB = cb.treat( + entitiesB, + EntityB.class + ); + selections.add( joinEntityB.get( "id" ) ); + selections.add( joinEntityB.get( "valueB" ) ); + + query.multiselect( selections ); + + final List resultList = em.createQuery( query ).getResultList(); + assertThat( resultList.size(), is( 10 ) ); + } + finally { + em.close(); + } + } + + @MappedSuperclass + public static abstract class MyEntity { + @Id + @GeneratedValue + private long id; + } + + @Entity(name = "TestEntity") + public static class TestEntity extends MyEntity { + @OneToMany(mappedBy = "parent", cascade = {CascadeType.ALL}) + private List entities = new ArrayList<>(); + } + + @Entity(name = "AbstractEntity") + public static abstract class AbstractEntity extends MyEntity { + String entityType = getClass().getName(); + + @ManyToOne + private TestEntity parent; + + public TestEntity getParent() { + return parent; + } + + public void setParent(TestEntity parent) { + this.parent = parent; + parent.entities.add( this ); + } + } + + @Entity(name = "EntityA") + public static class EntityA extends AbstractEntity { + public String valueA; + + public EntityA() { + super.entityType = getClass().getName(); + } + } + + @Entity(name = "EntityB") + public static class EntityB extends AbstractEntity { + public String valueB; + + public EntityB() { + super.entityType = getClass().getName(); + } + } +}