Announcement Announcement Module
Collapse
No announcement yet.
Query by specification, simple field and pageable Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Query by specification, simple field and pageable

    Hi,
    I've been using this method definition in a Spring Data JPA enabled repository:
    Code:
    List<User> findAllByTenant(final Specification<User> constraints, final String tenant);
    I have also used (from JpaSpecificationExecutor):
    Code:
    Page<T> findAll(Specification<T> spec, Pageable pageable);
    Now, trying to use:
    Code:
    Page<User> findAllByTenant(final Specification<User> constraints, final String tenant, final Pageable pageable);
    Fails with:
    Caused by: java.lang.IllegalArgumentException: Parameter value [org.springframework.data.jpa.domain.Specifications @4815e] did not match expected type [java.lang.String]
    at org.hibernate.ejb.AbstractQueryImpl.validateParame terBinding(AbstractQueryImpl.java:375)
    at org.hibernate.ejb.AbstractQueryImpl.registerParame terBinding(AbstractQueryImpl.java:348)
    at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl .java:375)
    at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl .java:328)
    at org.hibernate.ejb.criteria.CriteriaQueryCompiler$3 .setParameter(CriteriaQueryCompiler.java:322)
    at org.hibernate.ejb.criteria.CriteriaQueryCompiler$3 .setParameter(CriteriaQueryCompiler.java:251)
    at org.springframework.data.jpa.repository.query.Crit eriaQueryParameterBinder.bind(CriteriaQueryParamet erBinder.java:68)
    at org.springframework.data.jpa.repository.query.Para meterBinder.bind(ParameterBinder.java:108)
    at org.springframework.data.jpa.repository.query.Para meterBinder.bindAndPrepare(ParameterBinder.java:13 9)
    at org.springframework.data.jpa.repository.query.Para meterBinder.bindAndPrepare(ParameterBinder.java:13 4)
    at org.springframework.data.jpa.repository.query.Part TreeJpaQuery$QueryPreparer.invokeBinding(PartTreeJ paQuery.java:144)
    at org.springframework.data.jpa.repository.query.Part TreeJpaQuery$QueryPreparer.createQuery(PartTreeJpa Query.java:121)
    at org.springframework.data.jpa.repository.query.Part TreeJpaQuery.doCreateQuery(PartTreeJpaQuery.java:7 1)
    at org.springframework.data.jpa.repository.query.Abst ractJpaQuery.createQuery(AbstractJpaQuery.java:144 )
    at org.springframework.data.jpa.repository.query.JpaQ ueryExecution$CollectionExecution.doExecute(JpaQue ryExecution.java:77)
    at org.springframework.data.jpa.repository.query.JpaQ ueryExecution.execute(JpaQueryExecution.java:55)
    at org.springframework.data.jpa.repository.query.Abst ractJpaQuery.doExecute(AbstractJpaQuery.java:95)
    at org.springframework.data.jpa.repository.query.Abst ractJpaQuery.execute(AbstractJpaQuery.java:85)
    at org.springframework.data.repository.core.support.R epositoryFactorySupport$QueryExecutorMethodInterce ptor.invoke(RepositoryFactorySupport.java:313)
    at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :172)
    at org.springframework.transaction.interceptor.Transa ctionInterceptor.invoke(TransactionInterceptor.jav a:110)
    at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :172)
    at org.springframework.dao.support.PersistenceExcepti onTranslationInterceptor.invoke(PersistenceExcepti onTranslationInterceptor.java:155)
    ... 48 more


    So, essentially, it works with the specification and the simple field, it works with the specification and pagination, but it doesn't work with all 3.
    Is there anything I'm missing on this? Should it work or is this not supported?
    Thanks.
    Eugen.

  • #2
    Seems that
    Code:
    List<User> findAllByTenant(final Specification<User> constraints, final String tenant);
    doesn't work with the same exception.

    Comment


    • #3
      Currently Specification parameters are not "discovered" as special, non-bindable parameters (such as Pageable). Generally, we currently don't provide support for this as it's not clear how the given Specification shall be applied to the criteria built for the query method. Using AND? Using OR? How shall this work in case of a manually defined query method using @Query or a named query?

      What's wrong with just defining a dedicated Specification for the tenant clause and let the repository client apply that to the dynamically created one before executing the findAll(Specification<User> specification) method?

      Comment


      • #4
        Following up on this one - my original use case is not related to a manually specified @Query.
        On the question of how to apply the specification to the criteria, my thinking is that it needs to be AND; looking at this method:
        Code:
        Page<User> findAllByTenant(final Specification<User> constraints, final String tenant, final Pageable pageable);
        My reading of it is that it needs to construct the query criteria from the specification and then apply the paging on top of that, which is a natural usage of the API.
        Hope this clarifies the original intent of the question.
        Thanks.
        Eugen.

        Comment


        • #5
          Fine, this is how *you* want *your* case to be modeled. The problem is that we have to think about all the edge cases and potential combinations. I'd argue you can implement this behavior in a custom implementation combining the tenant and the Pageable to the given specification explicitly and execute it.

          It might still be worth opening a ticket to start working on well defined semantics for a general support of this.
          Last edited by Oliver Gierke; Dec 25th, 2012, 09:38 AM.

          Comment

          Working...
          X