Spring Data JPA
  1. Spring Data JPA
  2. DATAJPA-297

org.postgresql.util.PSQLException: ERROR: arguments of row IN must all be row expressions

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Works as Designed
    • Affects Version/s: 1.2 GA
    • Fix Version/s: None
    • Component/s: Core
    • Labels:
    • Environment:
      Eclipselink (Glassfish 3.2.2)
      Postgresql 9.1

      Description

      I have the following query method defined:

      -> List<Invitation> findByValueIn(Collection<String> values);

      The Invitation entity has a field named value and I pass a Set<String> into the query method.

      At runtime, when the query method is invoked, the following error is produced:

      -> 'ERROR: arguments of row IN must all be row expressions'

      The full stacktrace is available in the attached file.

      As a workaround, I wrote my own function using the JPA Criteria API.

        Activity

        Hide
        Oliver Gierke added a comment -

        I think what you're stumbling over is a bug in EclipseLink I already reported here. That bug is also the reason why I had to disable a few tests in out EclipseLink-specific test cases. So I am inclined to close this as works as designed. Thoughts?

        Show
        Oliver Gierke added a comment - I think what you're stumbling over is a bug in EclipseLink I already reported here . That bug is also the reason why I had to disable a few tests in out EclipseLink-specific test cases . So I am inclined to close this as works as designed. Thoughts?
        Hide
        Tony Davidson added a comment - - edited

        I wrote the following function, which works fine, to get around the issue:

            @Override
            public List<Invitation> findByValueIn(Collection<String> values) {
                CriteriaBuilder cb = em.getCriteriaBuilder();
                CriteriaQuery<Invitation> c = cb.createQuery(Invitation.class);
                Root<Invitation> inv = c.from(Invitation.class);
        
                c.select(inv).where(inv.get(Invitation_.value).in(values));
        
                TypedQuery<Invitation> i = em.createQuery(c);
        
                return i.getResultList();
            }
        

        After reading the bug you submitted to EclipseLink, I re-wrote the function as shown below:

            @Override
            public List<Invitation> findByValueIn(Collection<String> values) {
                CriteriaBuilder cb = em.getCriteriaBuilder();
                CriteriaQuery<Invitation> criteriaQuery = cb.createQuery(Invitation.class);
                Root<Invitation> inv = criteriaQuery.from(Invitation.class);
        
                criteriaQuery.select(inv).where(inv.get(Invitation_.value).in(cb.parameter(Collection.class)));
        
                TypedQuery<Invitation> query = em.createQuery(criteriaQuery);
        
                for(ParameterExpression parameterExpression : criteriaQuery.getParameters()) {
                    query.setParameter(parameterExpression, values);
                }
        
                return query.getResultList();
            }
        

        At runtime this function throws the same error I initially encountered. This confirms your assertion that this is actually a bug in EclipseLink.

        Thanks for taking the time to look at this. The issue can be closed.

        Show
        Tony Davidson added a comment - - edited I wrote the following function, which works fine, to get around the issue: @Override public List<Invitation> findByValueIn(Collection< String > values) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Invitation> c = cb.createQuery(Invitation.class); Root<Invitation> inv = c.from(Invitation.class); c.select(inv).where(inv.get(Invitation_.value).in(values)); TypedQuery<Invitation> i = em.createQuery(c); return i.getResultList(); } After reading the bug you submitted to EclipseLink, I re-wrote the function as shown below: @Override public List<Invitation> findByValueIn(Collection< String > values) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Invitation> criteriaQuery = cb.createQuery(Invitation.class); Root<Invitation> inv = criteriaQuery.from(Invitation.class); criteriaQuery.select(inv).where(inv.get(Invitation_.value).in(cb.parameter(Collection.class))); TypedQuery<Invitation> query = em.createQuery(criteriaQuery); for (ParameterExpression parameterExpression : criteriaQuery.getParameters()) { query.setParameter(parameterExpression, values); } return query.getResultList(); } At runtime this function throws the same error I initially encountered. This confirms your assertion that this is actually a bug in EclipseLink. Thanks for taking the time to look at this. The issue can be closed.
        Hide
        Oliver Gierke added a comment -

        The problem with the former approach is that the query created is not using placeholders then and thus is not subject to query caching. That's why introduced the additional step with the expression and parameter binding in the first place.

        Thanks for confirming, anyway!

        Show
        Oliver Gierke added a comment - The problem with the former approach is that the query created is not using placeholders then and thus is not subject to query caching. That's why introduced the additional step with the expression and parameter binding in the first place. Thanks for confirming, anyway!

          People

          • Assignee:
            Oliver Gierke
            Reporter:
            Tony Davidson
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: