HHH-10556 : Failure getting a PluralAttributePath for collection declared in a superclass marked @Entity

This commit is contained in:
Gail Badner 2016-03-09 16:51:51 -08:00
parent 4a54c911c1
commit 1c2107899a
3 changed files with 52 additions and 14 deletions

View File

@ -9,7 +9,10 @@ package org.hibernate.jpa.criteria.path;
import java.io.Serializable; import java.io.Serializable;
import javax.persistence.metamodel.Attribute; import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.Bindable; import javax.persistence.metamodel.Bindable;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.IdentifiableType;
import javax.persistence.metamodel.PluralAttribute; import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.Type;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.jpa.criteria.CriteriaBuilderImpl; import org.hibernate.jpa.criteria.CriteriaBuilderImpl;
@ -41,7 +44,38 @@ public class PluralAttributePath<X> extends AbstractPathImpl<X> implements Seria
} }
private String resolveRole(PluralAttribute attribute) { private String resolveRole(PluralAttribute attribute) {
return getPathSource().getJavaType().getName() + Class<?> roleOwnerType = attribute.getDeclaringType().getJavaType();
if ( attribute.getDeclaringType().getPersistenceType() == Type.PersistenceType.MAPPED_SUPERCLASS ) {
// the attribute is declared in a mappedsuperclass
if ( getPathSource().getModel().getBindableType() == Bindable.BindableType.ENTITY_TYPE ) {
// the role will be assigned to the "nearest" EnityType subclass of the MappedSuperclassType
EntityType entityTypeNearestDeclaringType = (EntityType) getPathSource().getModel();
IdentifiableType superType = entityTypeNearestDeclaringType.getSupertype();
IdentifiableType previousType = entityTypeNearestDeclaringType;
while ( superType != attribute.getDeclaringType() ) {
if ( superType == null ) {
throw new IllegalStateException(
String.format(
"Cannot determine nearest EntityType extending mapped superclass [%s]; [%s] extends [%s], but supertype of [%s] is null",
attribute.getDeclaringType().getJavaType().getName(),
( (EntityType) getPathSource().getModel() ).getJavaType().getName(),
previousType.getJavaType().getName(),
previousType.getJavaType().getName()
)
);
}
if ( superType.getPersistenceType() == Type.PersistenceType.ENTITY ) {
entityTypeNearestDeclaringType = (EntityType) superType;
}
previousType = superType;
superType = superType.getSupertype();
}
roleOwnerType = entityTypeNearestDeclaringType.getJavaType();
}
// else throw an exception?
}
// TODO: still need to deal with a plural attribute declared in an embeddable (HHH-6562)
return roleOwnerType.getName() +
'.' + attribute.getName(); '.' + attribute.getName();
} }

View File

@ -21,7 +21,6 @@ import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root; import javax.persistence.criteria.Root;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.FailureExpected;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.junit.Test; import org.junit.Test;
@ -42,7 +41,6 @@ public class EntitySuperclassCollectionTest extends BaseEntityManagerFunctionalT
@Test @Test
@TestForIssue( jiraKey = "HHH-10556") @TestForIssue( jiraKey = "HHH-10556")
@FailureExpected( jiraKey = "HHH-10556")
public void testPerson() { public void testPerson() {
String address = "super-address"; String address = "super-address";

View File

@ -23,7 +23,6 @@ import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root; import javax.persistence.criteria.Root;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.FailureExpected;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.junit.Test; import org.junit.Test;
@ -38,7 +37,7 @@ public class SuperclassCollectionTest extends BaseEntityManagerFunctionalTestCas
@Override @Override
protected Class<?>[] getAnnotatedClasses() { protected Class<?>[] getAnnotatedClasses() {
return new Class[] { return new Class[] {
PersonBase.class, Person.class, OtherPerson.class, Address.class, PersonBaseBase.class, Person.class, OtherPerson.class, Address.class,
OtherSubclass.class OtherSubclass.class
}; };
} }
@ -48,7 +47,7 @@ public class SuperclassCollectionTest extends BaseEntityManagerFunctionalTestCas
String address = "super-address"; String address = "super-address";
String localAddress = "local-address"; String localAddress = "local-address";
PersonBase person = createPerson( new Person(), address, localAddress ); PersonBaseBase person = createPerson( new Person(), address, localAddress );
assertAddress( person, address, localAddress ); assertAddress( person, address, localAddress );
} }
@ -57,24 +56,23 @@ public class SuperclassCollectionTest extends BaseEntityManagerFunctionalTestCas
public void testOtherSubclass() { public void testOtherSubclass() {
String address = "other-super-address"; String address = "other-super-address";
String localAddress = "other-local-address"; String localAddress = "other-local-address";
PersonBase person = createPerson( new OtherSubclass(), address, localAddress ); PersonBaseBase person = createPerson( new OtherSubclass(), address, localAddress );
assertAddress( person, address, localAddress ); assertAddress( person, address, localAddress );
} }
@Test @Test
@TestForIssue( jiraKey = "HHH-10556") @TestForIssue( jiraKey = "HHH-10556")
@FailureExpected( jiraKey = "HHH-10556")
public void testOtherPerson() { public void testOtherPerson() {
String address = "other-person-super-address"; String address = "other-person-super-address";
String localAddress = "other-person-local-address"; String localAddress = "other-person-local-address";
PersonBase person = createPerson( new OtherPerson(), address, localAddress ); PersonBaseBase person = createPerson( new OtherPerson(), address, localAddress );
assertAddress( person, address, localAddress ); assertAddress( person, address, localAddress );
} }
private void assertAddress(PersonBase person, String address, String localAddress) { private void assertAddress(PersonBaseBase person, String address, String localAddress) {
List<Object> results = find( person.getClass(), person.id, "addresses" ); List<Object> results = find( person.getClass(), person.id, "addresses" );
assertEquals( 1, results.size() ); assertEquals( 1, results.size() );
@ -91,7 +89,7 @@ public class SuperclassCollectionTest extends BaseEntityManagerFunctionalTestCas
getOrCreateEntityManager().close(); getOrCreateEntityManager().close();
} }
private PersonBase createPerson(PersonBase person, String address, String localAddress) { private PersonBaseBase createPerson(PersonBaseBase person, String address, String localAddress) {
EntityManager em = createEntityManager(); EntityManager em = createEntityManager();
EntityTransaction tx = em.getTransaction(); EntityTransaction tx = em.getTransaction();
tx.begin(); tx.begin();
@ -132,7 +130,7 @@ public class SuperclassCollectionTest extends BaseEntityManagerFunctionalTestCas
} }
@MappedSuperclass @MappedSuperclass
public abstract static class PersonBase { public abstract static class PersonBaseBase {
@Id @Id
@GeneratedValue @GeneratedValue
Integer id; Integer id;
@ -142,6 +140,10 @@ public class SuperclassCollectionTest extends BaseEntityManagerFunctionalTestCas
protected abstract List<Address> getLocalAddresses(); protected abstract List<Address> getLocalAddresses();
} }
@MappedSuperclass
public abstract static class PersonBase extends PersonBaseBase {
}
@Entity(name="Person") @Entity(name="Person")
public static class Person extends PersonBase { public static class Person extends PersonBase {
@OneToMany(cascade = CascadeType.ALL) @OneToMany(cascade = CascadeType.ALL)
@ -154,12 +156,16 @@ public class SuperclassCollectionTest extends BaseEntityManagerFunctionalTestCas
} }
} }
@MappedSuperclass
public static class OtherPersonBase extends Person {
}
@Entity(name="OtherPerson") @Entity(name="OtherPerson")
public static class OtherPerson extends Person { public static class OtherPerson extends OtherPersonBase {
} }
@Entity(name="OtherSubclass") @Entity(name="OtherSubclass")
public static class OtherSubclass extends PersonBase { public static class OtherSubclass extends PersonBaseBase {
@OneToMany(cascade = CascadeType.ALL) @OneToMany(cascade = CascadeType.ALL)
@JoinTable(name = "other_person_localaddress") @JoinTable(name = "other_person_localaddress")
List<Address> localAddresses = new ArrayList<Address>(); List<Address> localAddresses = new ArrayList<Address>();