Search code examples
javajpaeclipselinkquerydsl

QueryDSL JPA syntax error with contains on Set?


I have a JPA entity bean similar to the following:

@Entity
class License {
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "LicenseTags")
    Set<Tag> tags;

    // Skipped remaining members
}

Tag itself is also an Entity with an id and a name. Now I want to query for licenses that have certain tags attached to them. When I try the following query

Set<Tag> tags = ...;
final QLicense license = QLicense.license;
JPAQuery q = new JPAQuery(entityManager).from(license);

for (Tag tag : tags) {
    q.where(license.tags.contains(tag));
}

Collection<License> result = q.listDistinct(license);

I get the following Exception on the line with listDistinct

java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: 
Exception Description: Syntax error parsing the query [select distinct license
from License license
where ?1 in elements(license.tags)]: unexpected token [in].
Internal Exception: NoViableAltException(35!=[685:1: inExpression[boolean not, Object left] returns [Object node] : (t= IN n= inputParameter | t= IN LEFT_ROUND_BRACKET (itemNode= inItem ( COMMA itemNode= inItem )* | subqueryNode= subquery ) RIGHT_ROUND_BRACKET );])
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1328)
    at com.sun.enterprise.container.common.impl.EntityManagerWrapper.createQuery(EntityManagerWrapper.java:425)
    at com.mysema.query.jpa.impl.DefaultSessionHolder.createQuery(DefaultSessionHolder.java:35)
    at com.mysema.query.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:139)
    at com.mysema.query.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:108)
    at com.mysema.query.jpa.impl.AbstractJPAQuery.list(AbstractJPAQuery.java:276)
    at com.mysema.query.support.ProjectableQuery.listDistinct(ProjectableQuery.java:104)

From the parser exception output I can only guess that maybe there are parenthesis missing.

Am I doing something wrong to query for values contained in the set?

I am using GlassFish Server Open Source Edition 3.0.1 (build 22) which in turn uses EclipseLink Bundle-Version: 2.0.1.v20100213-r6600

Regards, Tilmann


Solution

  • Looks like you are using the Hibernate templates in your JPA query. Try this instead

    JPAQuery query = new JPAQuery (entityManager, EclipseLinkTemplates.DEFAULT); 
    

    From the next release on there will be an autodetection of the JPA provider and proper templates for JPQL usage will be chosen based on that.

    The current logic is described though in the reference manual http://www.querydsl.com/static/querydsl/2.6.0/reference/html/ch02.html#d0e185

    Also you might try to express your query like this

    List<License> result = query.from(license)
        .where(license.tags.any().in(tags))
        .listDistinct(license);