Reputation: 10652
assuming I have the following entities:
@Entity
public class Word { ... }
@Entity
public class Noun extends Word { ... }
@Entity
public class Verb extends Word { ... }
(Plus the usual Disriminator- and Join-Strategy stuff, simply assume that the entities work fine, which they do.)
I tried ...
public interface WordRepository extends CrudRepository<Word, Long>{
@Query("SELECT x FROM Word x WHERE type(x) = ?1")
<T extends Word> List<T> findByClass(Class<T> clz);
}
...but this gives me an exception, caused by:
org.hibernate.QueryException: Not all named parameters have been set: [1] [SELECT x FROM Word x WHERE type(x) = ?1]
One solution is to replace Class<T>
with Class<?>
, then the code works, but obviously that's not type-safe anymore since then I can write...
List<Verb> verbs = repository.findByClass(Noun.class);
...which runs, but obviously throws a ClassCastException
whenever I try to access the verbs (
since all the objects in the list are actually Nouns
, not Verbs
)
Is there any way to write this type-safe with spring-data, preferably without hardcoding all types into their own methods (findNouns
, findVerbs
, etc.) or defining Repositories
for all types?
Edit: The problem seems to be the Parameter.isDynamicProjectionParameter(MethodParameter)
method, that seems to define a special behavior for Class<T>
parameters, so they are only used for dynamic parameters but cannot be given into the query itself. Hm. Wish anyone had a way around that.
Upvotes: 5
Views: 1971
Reputation: 1475
I just faced the same issue. For your/every other user´s information i filed a spring data jpa issue, which you folks can follow here: https://jira.spring.io/browse/DATAJPA-1257
Upvotes: 3