HHH-9411 : Fix downcast of treat statement.
This commit is contained in:
parent
4fb11c9919
commit
b8a3774cb4
|
@ -620,6 +620,21 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
||||||
if ( !queryable.isAbstract() ) {
|
if ( !queryable.isAbstract() ) {
|
||||||
values.add( queryable.getDiscriminatorSQLValue() );
|
values.add( queryable.getDiscriminatorSQLValue() );
|
||||||
}
|
}
|
||||||
|
else if ( queryable.hasSubclasses() ) {
|
||||||
|
// if the treat is an abstract class, add the concrete implementations to values if any
|
||||||
|
Set<String> actualSubClasses = queryable.getEntityMetamodel().getSubclassEntityNames();
|
||||||
|
|
||||||
|
for ( String actualSubClass : actualSubClasses ) {
|
||||||
|
if ( actualSubClass.equals( subclass ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Queryable actualQueryable = (Queryable) getFactory().getEntityPersister( actualSubClass );
|
||||||
|
if ( !actualQueryable.hasSubclasses() ) {
|
||||||
|
values.add( actualQueryable.getDiscriminatorSQLValue() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return values.toArray( new String[values.size()] );
|
return values.toArray( new String[values.size()] );
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,14 +11,17 @@ import javax.persistence.DiscriminatorType;
|
||||||
import javax.persistence.DiscriminatorValue;
|
import javax.persistence.DiscriminatorValue;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.FetchType;
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Inheritance;
|
import javax.persistence.Inheritance;
|
||||||
import javax.persistence.InheritanceType;
|
import javax.persistence.InheritanceType;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.Transaction;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -38,7 +41,8 @@ public class TreatKeywordTest extends BaseCoreFunctionalTestCase {
|
||||||
return new Class[] {
|
return new Class[] {
|
||||||
JoinedEntity.class, JoinedEntitySubclass.class, JoinedEntitySubSubclass.class,
|
JoinedEntity.class, JoinedEntitySubclass.class, JoinedEntitySubSubclass.class,
|
||||||
JoinedEntitySubclass2.class, JoinedEntitySubSubclass2.class,
|
JoinedEntitySubclass2.class, JoinedEntitySubSubclass2.class,
|
||||||
DiscriminatorEntity.class, DiscriminatorEntitySubclass.class, DiscriminatorEntitySubSubclass.class
|
DiscriminatorEntity.class, DiscriminatorEntitySubclass.class, DiscriminatorEntitySubSubclass.class,
|
||||||
|
Animal.class, Dog.class, Dachshund.class, Greyhound.class
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,6 +188,25 @@ public class TreatKeywordTest extends BaseCoreFunctionalTestCase {
|
||||||
s.close();
|
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" )
|
@Entity( name = "JoinedEntity" )
|
||||||
@Table( name = "JoinedEntity" )
|
@Table( name = "JoinedEntity" )
|
||||||
@Inheritance( strategy = InheritanceType.JOINED )
|
@Inheritance( strategy = InheritanceType.JOINED )
|
||||||
|
@ -334,4 +357,38 @@ public class TreatKeywordTest extends BaseCoreFunctionalTestCase {
|
||||||
super( id, name, 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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,13 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.jpa.test.criteria;
|
package org.hibernate.jpa.test.criteria;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityTransaction;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
import javax.persistence.criteria.CriteriaBuilder;
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
import javax.persistence.criteria.CriteriaQuery;
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
import javax.persistence.criteria.Root;
|
import javax.persistence.criteria.Root;
|
||||||
|
@ -22,6 +27,8 @@ import org.hibernate.testing.TestForIssue;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
@ -29,7 +36,10 @@ public class TreatKeywordTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<?>[] getAnnotatedClasses() {
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
return new Class[] { Animal.class, Elephant.class, Human.class, Thing.class, ThingWithQuantity.class };
|
return new Class[] {
|
||||||
|
Animal.class, Elephant.class, Human.class, Thing.class, ThingWithQuantity.class,
|
||||||
|
TreatAnimal.class, Dog.class, Dachshund.class, Greyhound.class
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -213,4 +223,68 @@ public class TreatKeywordTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-9411")
|
||||||
|
public void testTreatWithRestrictionOnAbstractClass() {
|
||||||
|
EntityManager em = getOrCreateEntityManager();
|
||||||
|
EntityTransaction entityTransaction = em.getTransaction();
|
||||||
|
entityTransaction.begin();
|
||||||
|
|
||||||
|
Greyhound greyhound = new Greyhound();
|
||||||
|
Dachshund dachshund = new Dachshund();
|
||||||
|
em.persist( greyhound );
|
||||||
|
em.persist( dachshund );
|
||||||
|
|
||||||
|
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<TreatAnimal> criteriaQuery = cb.createQuery( TreatAnimal.class );
|
||||||
|
|
||||||
|
Root<TreatAnimal> animal = criteriaQuery.from( TreatAnimal.class );
|
||||||
|
|
||||||
|
Root<Dog> dog = cb.treat( animal, Dog.class );
|
||||||
|
|
||||||
|
// only fast dogs
|
||||||
|
criteriaQuery.where( cb.isTrue( dog.<Boolean>get( "fast" ) ) );
|
||||||
|
|
||||||
|
List<TreatAnimal> results = em.createQuery( criteriaQuery ).getResultList();
|
||||||
|
|
||||||
|
// we should only have a single Greyhound here, not slow long dogs!
|
||||||
|
assertEquals( Arrays.asList( greyhound ), results );
|
||||||
|
|
||||||
|
entityTransaction.commit();
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public static abstract class TreatAnimal {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public static abstract class Dog extends TreatAnimal {
|
||||||
|
private boolean fast;
|
||||||
|
|
||||||
|
protected Dog(boolean fast) {
|
||||||
|
this.fast = fast;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean isFast() {
|
||||||
|
return fast;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public static class Dachshund extends Dog {
|
||||||
|
public Dachshund() {
|
||||||
|
super( false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public static class Greyhound extends Dog {
|
||||||
|
public Greyhound() {
|
||||||
|
super( true );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue