Florian Schaetz
Florian Schaetz

Reputation: 10652

Spring-Data Repository @Query by class with generic class

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

Answers (1)

Thomas Lang
Thomas Lang

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

Related Questions