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 javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.Bindable;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.IdentifiableType;
import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.Type;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.jpa.criteria.CriteriaBuilderImpl;
@ -41,7 +44,38 @@ public class PluralAttributePath<X> extends AbstractPathImpl<X> implements Seria
}
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();
}

View File

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

View File

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