HHH-10556 : Failure getting a PluralAttributePath for collection declared in a superclass marked @Entity
This commit is contained in:
parent
4a54c911c1
commit
1c2107899a
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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";
|
||||||
|
|
||||||
|
|
|
@ -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>();
|
||||||
|
|
Loading…
Reference in New Issue