0

In Game entity i have :

private Set<GameGenre> genres = new HashSet<>();

I wrote custom query that will filter games by genre id. When i hardcode genre id in query it works :

@Query("select new com.twognation.hub.dto.GameDTO(game.id, game.name, game.active, game.description, game.coverImage, game.logo, game.backgroundImage, game.featuredImage, game.characterImage, game.smallCoverImage, count(tournament.id) as tournamentCount) from Game game left join Tournament tournament on game.id=tournament.game inner join game.genres genres where lower(game.name) like CONCAT('%', :name, '%') and genres IN (1301) group by game.id order by tournamentCount desc, game.id")

But when i try to pass list of ids :

@Query("select new com.twognation.hub.dto.GameDTO(game.id, game.name, game.active, game.description, game.coverImage, game.logo, game.backgroundImage, game.featuredImage, game.characterImage, game.smallCoverImage, count(tournament.id) as tournamentCount) from Game game left join Tournament tournament on game.id=tournament.game inner join game.genres genres where lower(game.name) like CONCAT('%', :name, '%') and genres IN (:genres) group by game.id order by tournamentCount desc, game.id")
    Page<GameDTO> findAllOrderByTournamentCountAndGenreFilter(@Param("name") String name, @Param("genres") String genres, Pageable page);

i get this error :

Caused by: java.lang.IllegalArgumentException: Parameter value [1301] did not match expected type [com.twognation.hub.domain.GameGenre (n/a)]
    at org.hibernate.query.spi.QueryParameterBindingValidator.validate(QueryParameterBindingValidator.java:54)
    at org.hibernate.query.spi.QueryParameterBindingValidator.validate(QueryParameterBindingValidator.java:27)
    at org.hibernate.query.internal.QueryParameterBindingImpl.validate(QueryParameterBindingImpl.java:90)
    at org.hibernate.query.internal.QueryParameterBindingImpl.setBindValue(QueryParameterBindingImpl.java:55)
    at org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:486)
    at org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:104)
    at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:139)
    at org.springframework.data.jpa.repository.query.StringQueryParameterBinder.bind(StringQueryParameterBinder.java:61)
    at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:101)
    at org.springframework.data.jpa.repository.query.SpelExpressionStringQueryParameterBinder.bind(SpelExpressionStringQueryParameterBinder.java:76)
    at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:161)
    at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:152)
    at org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery.doCreateQuery(AbstractStringBasedJpaQuery.java:81)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:190)
    at org.springframework.data.jpa.repository.query.JpaQueryExecution$PagedExecution.doExecute(JpaQueryExecution.java:186)
    at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:87)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:116)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:106)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:492)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:475)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    ... 172 common frames omitted

Game entity :

@Entity
@Table(name = "game")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Document(indexName = "game")
public class Game implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
    @SequenceGenerator(name = "sequenceGenerator")
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "active")
    private Boolean active;

    @Lob
    @Column(name = "description")
    private String description;

    @Column(name = "cover_image")
    private String coverImage;

    @Column(name = "logo")
    private String logo;

    @Column(name = "background_image")
    private String backgroundImage;

    @Column(name = "featured_image")
    private String featuredImage;

    @Column(name = "character_image")
    private String characterImage;

    @Column(name = "small_cover_image")
    private String smallCoverImage;

    @ManyToMany
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    @JoinTable(name = "game_genres",
               joinColumns = @JoinColumn(name="games_id", referencedColumnName="id"),
               inverseJoinColumns = @JoinColumn(name="genres_id", referencedColumnName="id"))
    private Set<GameGenre> genres = new HashSet<>();

2 Answers 2

2

Your query should be and genres.genreId IN (:genres).

@Query("select new com.twognation.hub.dto.GameDTO(game.id, game.name, game.active, game.description, game.coverImage, game.logo, game.backgroundImage, game.featuredImage, game.characterImage, game.smallCoverImage, count(tournament.id) as tournamentCount) from Game game left join Tournament tournament on game.id=tournament.game inner join game.genres genres where lower(game.name) like CONCAT('%', :name, '%') and genres.genreId IN (:genres) group by game.id order by tournamentCount desc, game.id")
Page<GameDTO> findAllOrderByTournamentCountAndGenreFilter(@Param("name") String name, @Param("genres") String genres, Pageable page);

genres is the entity and genreId is the variable name mapped to genre_id(I guess).

UPDATE:

After OP added the entity class.

When passing as Param you are explicitly mentioning it to be String which causes IllegalArgumentException as the entity expects HashSet<GameGenre>.

So the method signature should be,

Page<GameDTO> findAllOrderByTournamentCountAndGenreFilter(@Param("name") String name, @Param("genres") HashSet<GameGenre> genres, Pageable page);

and you should pass the Param as,

GameGenre gameGenre = new GameGenre();
gameGenre.setGenreId(1301);

HashSet<GameGenre> genres = new HashSet<GameGenre>();
geners.add(gameGenre);

Hope this helps.

Sign up to request clarification or add additional context in comments.

2 Comments

how does it work with hardcoded id line in my example ?
can you post your entity classes ?
1

You probably need to pass an object of the type GameGenre and not a String. Maybe also a Collection of GameGenre objects.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.