【问题标题】:QueryDSL JPA syntax error with contains on Set?QueryDSL JPA 语法错误,包含在 Set 上?
【发布时间】:2012-06-18 13:20:14
【问题描述】:

我有一个类似于以下的 JPA 实体 bean:

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

    // Skipped remaining members
}

Tag 本身也是一个 Entity,带有一个 id 和一个名称。现在我想查询附加了某些标签的许可证。当我尝试以下查询时

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);

我在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)

从解析器异常输出我只能猜测可能缺少括号。

我在查询集合中包含的值时做错了吗?

我正在使用 GlassFish Server Open Source Edition 3.0.1(内部版本 22),而后者又使用 EclipseLink Bundle-Version:2.0.1.v20100213-r6600

问候,蒂尔曼

【问题讨论】:

  • 尝试使用 JPA 解决方案可能吗? CriteriaBuilder.in().
  • 其实上面只是一个摘录,在同一个查询中还有很多其他的搜索条件。我们只是将它从 CriteriaBuilder 迁移到 QueryDSL,因为查询的 CB 语法版本变得非常模糊。 ;)
  • 我同意你的看法,不错的选择。

标签: java jpa eclipselink querydsl


【解决方案1】:

看起来您在 JPA 查询中使用了 Hibernate 模板。试试这个

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

从下一个版本开始,将自动检测 JPA 提供程序,并根据此选择适当的 JPQL 使用模板。

目前的逻辑在参考手册http://www.querydsl.com/static/querydsl/2.6.0/reference/html/ch02.html#d0e185中有描述

您也可以尝试这样表达您的查询

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

【讨论】:

  • 非常感谢 Timo 的富有洞察力的回复。我不知道必须选择方言模板 :) 这解决了我遇到的语法问题 :) 但是:您提供的缩写查询无法按预期工作。我在这里记录了这一点:stackoverflow.com/questions/11088064/…
  • 好的,我也会调查这个问题。
【解决方案2】:

可能是缺少括号,或者可能是“元素”,我不确定它是 JPQL 的一部分。

尝试直接执行 JPQL 以确定问题所在。

您的查询似乎也非常低效,您应该只使用从许可证到标签的连接。

【讨论】:

  • 是的,对于提到的检查,我可以使用加入 :) 但接下来我会遇到麻烦,以便下一步实施:仅列出 没有 的许可证给定的标签。在我们使用查询时,性能不是问题。
猜你喜欢
  • 2014-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 1970-01-01
  • 2014-06-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多