Closed spring-projects-issues closed 5 years ago
Oliver Drotbohm commented
Using @MappedSuperclass
currently is supported but requires the identifier property to be contained in it. See AbstractPersistable
for example.
I am not quite sure in how far it makes sense to not include the identifier property in that class as that could mean different identifier types in various sub-types, which in turn raises the question how a findOne(…)
is supposed to work properly (i.e. I am not even sure persistence providers support EntityManager.find(id, type)
with a mapped superclass, especially with entities using a compound key like with {{@IdClass
}). Happy to explore opportunities though
Thomas Beauvais commented
Thank you for the response though I am not sure if I follow. This is perfectly legal in JPA and Hibernate. The sub-classes have the same ID typed, though unfortunately they are named different.
Please check the reference URL to understand the problem fully. Let me know if there is anything else I can provide
Oliver Drotbohm commented
I think I understood the problem entirely. I know that this is supported by JPA, however, until now it's not for Spring Data :). I guess mostly because nobody as asked so far. Again, I suggest the workaround to declare the identifier property on the mapped superclass and use @AttributeOverride
in the subclasses until this is fixed
Thomas Beauvais commented
With the following model
@MappedSuperclass
public abstract class Element extends AbstractPersistable<Long> {
}
@Entity
@Table(name = "primary_element")
@AttributeOverride(name = "id", column = @Column(name = "eid"))
public class PrimaryElement extends Element implements Serializable {
}
@Entity
@Table(name = "working_element")
@AttributeOverride(name = "id", column = @Column(name = "weid"))
public class WorkingElement extends Element implements Serializable {
}
I get the following exception..
Caused by: java.lang.IllegalArgumentException: Not an entity: class lacuna.model.Element
at java.lang.reflect.Method.invoke(Method.java:497)
at org.hibernate.jpa.internal.metamodel.MetamodelImpl.entity(MetamodelImpl.java:203)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:434)
at org.hibernate.jpa.criteria.QueryStructure.from(QueryStructure.java:139)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:419)
at org.hibernate.jpa.criteria.CriteriaQueryImpl.from(CriteriaQueryImpl.java:173)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.javaat org.springframework.data.jpa.repository.support.SimpleJpaRepository.applySpecificationToCriteria(SimpleJpaRepository.java:568)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:526)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:315)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:67)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at java.lang.reflect.Method.invoke(Method.java:497)
Oliver Drotbohm commented
I am not quite how that relates to the original feature request, but a from(…)
by definition requires to be used with an entity type (see the spec and JavaDoc). For polymorphic queries, Element
has to be an entity. I haven't been part of the EG when this was defined but I guess this restriction is due to mapped superclasses being defined as table-less (see 2.11.2, JPA 2.0 spec) and inheritance strategies only being definable on entities.
Please let's not side track this ticket with general JPA mapping support requests
Thomas Beauvais commented
How can I side track my own ticket?
Element
doesn't have it's own table yet shares properties with the sub-classes. They are defined in each of the sub-classes tables. So, the @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
should work but it's not.
It will work when I create two separate Repository
interfaces. One for PrimaryElement
and one for WorkingElement
but not if I want to create a generic ElementRepository
.
public interface ElementRepository extends CrudRepository<Element, Long> {
}
Oliver Drotbohm commented
Because "side-tracking" is not defined by who created the ticket but what the ticket deals with. As already stated, mapped superclasses are currently only supported if they contain the id declaration. I acknowledged that and turned this into a feature request.
This however has nothing to do with general query abilities in JPA, which doesn't support a mapped superclass in a select clause. These are unrelated issues, hence my request for not mixing up one with the other. If it's about general JPA mapping related issues, I suggest to move to StackOverflow
Jens Schauder commented
The discussion seems to have died. Closing the issue
Thomas Beauvais opened DATAJPA-782 and commented
I have an extremely valid model where a couple classes extend a
@MappedSuperclass
. I want to create a base repository in which I can find all of the super class and return the correct instances. This is doable. Spring Data JPA is throwing cryptic errors and I can't find any documentation on getting this to work. I have also tried@Inheritence
and@Enity
and that is an even deeper hole. Can you please provide some insight into this?Affects: 1.8.2 (Fowler SR2)
Reference URL: http://stackoverflow.com/questions/32142718/hibernate-jpa-cant-map-different-id-for-sub-class?noredirect=1#comment52175230_32142718