4

次のような JPA エンティティ Bean があります。

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

    // Skipped remaining members
}

Tagそれ自体もEntityID と名前を持つ です。ここで、特定のタグが添付されたライセンスを照会したいと考えています。次のクエリを試すと

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 を使用します。

よろしく、 ティルマン

4

2 に答える 2

6

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); 
于 2012-06-18T14:01:59.697 に答える
1

ブラケットがないか、「要素」である可能性があります。それが JPQL の一部であるかどうかはわかりません。

JPQL を直接実行して、何が問題なのかを判断してください。

クエリも非常に非効率的です。代わりに、ライセンスからタグへの結合を使用する必要があります。

于 2012-06-18T13:28:26.220 に答える