/* * 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.jpa.ql; import javax.persistence.DiscriminatorColumn; import javax.persistence.DiscriminatorType; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.ManyToOne; import javax.persistence.Table; import java.util.Arrays; import java.util.List; import org.hibernate.Session; import org.hibernate.Transaction; import org.junit.Test; import org.hibernate.testing.FailureExpected; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * @author Steve Ebersole */ public class TreatKeywordTest extends BaseCoreFunctionalTestCase { @Override protected Class<?>[] getAnnotatedClasses() { return new Class[] { JoinedEntity.class, JoinedEntitySubclass.class, JoinedEntitySubSubclass.class, JoinedEntitySubclass2.class, JoinedEntitySubSubclass2.class, DiscriminatorEntity.class, DiscriminatorEntitySubclass.class, DiscriminatorEntitySubSubclass.class, Animal.class, Dog.class, Dachshund.class, Greyhound.class }; } @Test public void testBasicUsageInJoin() { // todo : assert invalid naming of non-subclasses in TREAT statement Session s = openSession(); s.createQuery( "from DiscriminatorEntity e join treat(e.other as DiscriminatorEntitySubclass) o" ).list(); s.createQuery( "from DiscriminatorEntity e join treat(e.other as DiscriminatorEntitySubSubclass) o" ).list(); s.createQuery( "from DiscriminatorEntitySubclass e join treat(e.other as DiscriminatorEntitySubSubclass) o" ).list(); s.createQuery( "from JoinedEntity e join treat(e.other as JoinedEntitySubclass) o" ).list(); s.createQuery( "from JoinedEntity e join treat(e.other as JoinedEntitySubSubclass) o" ).list(); s.createQuery( "from JoinedEntitySubclass e join treat(e.other as JoinedEntitySubSubclass) o" ).list(); s.close(); } @Test @TestForIssue( jiraKey = "HHH-8637" ) public void testFilteringDiscriminatorSubclasses() { Session s = openSession(); s.beginTransaction(); DiscriminatorEntity root = new DiscriminatorEntity( 1, "root" ); s.save( root ); DiscriminatorEntitySubclass child = new DiscriminatorEntitySubclass( 2, "child", root ); s.save( child ); s.getTransaction().commit(); s.close(); s = openSession(); s.beginTransaction(); // in select clause List result = s.createQuery( "select e from DiscriminatorEntity e" ).list(); assertEquals( 2, result.size() ); result = s.createQuery( "select treat (e as DiscriminatorEntitySubclass) from DiscriminatorEntity e" ).list(); assertEquals( 1, result.size() ); result = s.createQuery( "select treat (e as DiscriminatorEntitySubSubclass) from DiscriminatorEntity e" ).list(); assertEquals( 0, result.size() ); // in join result = s.createQuery( "from DiscriminatorEntity e inner join e.other" ).list(); assertEquals( 1, result.size() ); result = s.createQuery( "from DiscriminatorEntity e inner join treat (e.other as DiscriminatorEntitySubclass)" ).list(); assertEquals( 0, result.size() ); result = s.createQuery( "from DiscriminatorEntity e inner join treat (e.other as DiscriminatorEntitySubSubclass)" ).list(); assertEquals( 0, result.size() ); s.close(); s = openSession(); s.beginTransaction(); s.delete( root ); s.delete( child ); s.getTransaction().commit(); s.close(); } @Test @TestForIssue( jiraKey = "HHH-8637" ) public void testFilteringJoinedSubclasses() { Session s = openSession(); s.beginTransaction(); JoinedEntity root = new JoinedEntity( 1, "root" ); s.save( root ); JoinedEntitySubclass child = new JoinedEntitySubclass( 2, "child", root ); s.save( child ); s.getTransaction().commit(); s.close(); s = openSession(); s.beginTransaction(); // in the select clause which causes an implicit inclusion of subclass joins, the test here makes sure that // the TREAT-AS effects the join-type used. List result = s.createQuery( "select e from JoinedEntity e" ).list(); assertEquals( 2, result.size() ); result = s.createQuery( "select treat (e as JoinedEntitySubclass) from JoinedEntity e" ).list(); assertEquals( 1, result.size() ); result = s.createQuery( "select treat (e as JoinedEntitySubSubclass) from JoinedEntity e" ).list(); assertEquals( 0, result.size() ); // in join result = s.createQuery( "from JoinedEntity e inner join e.other" ).list(); assertEquals( 1, result.size() ); result = s.createQuery( "from JoinedEntity e inner join treat (e.other as JoinedEntitySubclass)" ).list(); assertEquals( 0, result.size() ); result = s.createQuery( "from JoinedEntity e inner join treat (e.other as JoinedEntitySubSubclass)" ).list(); assertEquals( 0, result.size() ); s.close(); s = openSession(); s.beginTransaction(); s.delete( child ); s.delete( root ); s.getTransaction().commit(); s.close(); } @Test @TestForIssue( jiraKey = "HHH-9862" ) @FailureExpected( jiraKey = "HHH-9862" ) public void testRestrictionsOnJoinedSubclasses() { Session s = openSession(); s.beginTransaction(); JoinedEntity root = new JoinedEntity( 1, "root" ); s.save( root ); JoinedEntitySubclass child1 = new JoinedEntitySubclass( 2, "child1", root ); s.save( child1 ); JoinedEntitySubclass2 child2 = new JoinedEntitySubclass2( 3, "child2", root ); s.save( child2 ); s.getTransaction().commit(); s.close(); s = openSession(); s.beginTransaction(); List result = s.createQuery( "select e from JoinedEntity e where treat (e as JoinedEntitySubclass ).name = 'child1'" ).list(); assertEquals( 1, result.size() ); assertTrue( JoinedEntitySubclass.class.isInstance( result.get( 0 ) ) ); result = s.createQuery( "select e from JoinedEntity e where treat (e as JoinedEntitySubclass2 ).name = 'child1'" ).list(); assertEquals( 0, result.size() ); result = s.createQuery( "select e from JoinedEntity e where treat (e as JoinedEntitySubclass2 ).name = 'child2'" ).list(); assertEquals( 1, result.size() ); assertTrue( JoinedEntitySubclass2.class.isInstance( result.get( 0 ) ) ); result = s.createQuery( "select e from JoinedEntity e where treat (e as JoinedEntitySubclass ).name = 'child1' or treat (e as JoinedEntitySubclass2 ).name = 'child2'" ).list(); assertEquals( 2, result.size() ); s.close(); s = openSession(); s.beginTransaction(); s.delete( child1 ); s.delete( child2 ); s.delete( root ); s.getTransaction().commit(); s.close(); } @Test @TestForIssue(jiraKey = "HHH-9411") public void testTreatWithRestrictionOnAbstractClass() { Session s = openSession(); Transaction tx = s.beginTransaction(); Greyhound greyhound = new Greyhound(); Dachshund dachshund = new Dachshund(); s.save( greyhound ); s.save( dachshund ); List results = s.createQuery( "select treat (a as Dog) from Animal a where a.fast = TRUE" ).list(); assertEquals( Arrays.asList( greyhound ), results ); tx.commit(); s.close(); } @Entity( name = "JoinedEntity" ) @Table( name = "JoinedEntity" ) @Inheritance( strategy = InheritanceType.JOINED ) public static class JoinedEntity { @Id public Integer id; public String name; @ManyToOne( fetch = FetchType.LAZY ) public JoinedEntity other; public JoinedEntity() { } public JoinedEntity(Integer id, String name) { this.id = id; this.name = name; } public JoinedEntity(Integer id, String name, JoinedEntity other) { this.id = id; this.name = name; this.other = other; } } @Entity( name = "JoinedEntitySubclass" ) @Table( name = "JoinedEntitySubclass" ) public static class JoinedEntitySubclass extends JoinedEntity { public JoinedEntitySubclass() { } public JoinedEntitySubclass(Integer id, String name) { super( id, name ); } public JoinedEntitySubclass(Integer id, String name, JoinedEntity other) { super( id, name, other ); } } @Entity( name = "JoinedEntitySubSubclass" ) @Table( name = "JoinedEntitySubSubclass" ) public static class JoinedEntitySubSubclass extends JoinedEntitySubclass { public JoinedEntitySubSubclass() { } public JoinedEntitySubSubclass(Integer id, String name) { super( id, name ); } public JoinedEntitySubSubclass(Integer id, String name, JoinedEntity other) { super( id, name, other ); } } @Entity( name = "JoinedEntitySubclass2" ) @Table( name = "JoinedEntitySubclass2" ) public static class JoinedEntitySubclass2 extends JoinedEntity { public JoinedEntitySubclass2() { } public JoinedEntitySubclass2(Integer id, String name) { super( id, name ); } public JoinedEntitySubclass2(Integer id, String name, JoinedEntity other) { super( id, name, other ); } } @Entity( name = "JoinedEntitySubSubclass2" ) @Table( name = "JoinedEntitySubSubclass2" ) public static class JoinedEntitySubSubclass2 extends JoinedEntitySubclass2 { public JoinedEntitySubSubclass2() { } public JoinedEntitySubSubclass2(Integer id, String name) { super( id, name ); } public JoinedEntitySubSubclass2(Integer id, String name, JoinedEntity other) { super( id, name, other ); } } @Entity( name = "DiscriminatorEntity" ) @Table( name = "DiscriminatorEntity" ) @Inheritance( strategy = InheritanceType.SINGLE_TABLE ) @DiscriminatorColumn( name = "e_type", discriminatorType = DiscriminatorType.STRING ) @DiscriminatorValue( "B" ) public static class DiscriminatorEntity { @Id public Integer id; public String name; @ManyToOne( fetch = FetchType.LAZY ) public DiscriminatorEntity other; public DiscriminatorEntity() { } public DiscriminatorEntity(Integer id, String name) { this.id = id; this.name = name; } public DiscriminatorEntity( Integer id, String name, DiscriminatorEntity other) { this.id = id; this.name = name; this.other = other; } } @Entity( name = "DiscriminatorEntitySubclass" ) @DiscriminatorValue( "S" ) public static class DiscriminatorEntitySubclass extends DiscriminatorEntity { public DiscriminatorEntitySubclass() { } public DiscriminatorEntitySubclass(Integer id, String name) { super( id, name ); } public DiscriminatorEntitySubclass( Integer id, String name, DiscriminatorEntity other) { super( id, name, other ); } } @Entity( name = "DiscriminatorEntitySubSubclass" ) @DiscriminatorValue( "SS" ) public static class DiscriminatorEntitySubSubclass extends DiscriminatorEntitySubclass { public DiscriminatorEntitySubSubclass() { } public DiscriminatorEntitySubSubclass(Integer id, String name) { super( id, name ); } public DiscriminatorEntitySubSubclass( Integer id, String name, DiscriminatorEntity other) { super( id, name, other ); } } @Entity(name = "Animal") public static abstract class Animal { @Id @GeneratedValue private Long id; } @Entity(name = "Dog") public static abstract class Dog extends Animal { private boolean fast; protected Dog(boolean fast) { this.fast = fast; } public final boolean isFast() { return fast; } } @Entity(name = "Dachshund") public static class Dachshund extends Dog { public Dachshund() { super( false ); } } @Entity(name = "Greyhound") public static class Greyhound extends Dog { public Greyhound() { super( true ); } } }