JPA条件订购者:意外的AST节点
我有下面的条件查询,它从JPA条件订购者:意外的AST节点,jpa,criteria-api,Jpa,Criteria Api,我有下面的条件查询,它从Anfrage和Sparte实体中检索一些字段,以及Sparte.i18nKey的翻译字符串。 如果我不使用orderBy,这将按预期工作 现在我需要按照翻译后的字符串对sparte.i18nKey进行排序,并使用orderBy如下所示,结果是QuerySyntaxException:unexpected AST node 所以问题一定是orderBy子句中的子选择 select distinct new my.domain.model.dto.AnfrageDTO(
Anfrage
和Sparte
实体中检索一些字段,以及Sparte.i18nKey
的翻译字符串。
如果我不使用orderBy,这将按预期工作
现在我需要按照翻译后的字符串对sparte.i18nKey
进行排序,并使用orderBy
如下所示,结果是QuerySyntaxException:unexpected AST node
所以问题一定是orderBy
子句中的子选择
select distinct new
my.domain.model.dto.AnfrageDTO(
anfrage0.id,
anfrage0.name,
anfrage0.sparte.id,
anfrage0.sparte.i18nKey,
-- retrieve translated string for sparte.i18nKey
(select rb0.value from at.luxbau.mis2.domain.model.ResourceBundleEntity as rb0
where (anfrage0.sparte.i18nKey = rb0.key) and (rb0.language = 'de'))
)
from my.domain.model.impl.Anfrage as anfrage0
left join anfrage0.sparte as sparte
order by (
-- sort by translated string for sparte.i18nKey
select rb1.value
from my.domain.model.ResourceBundleEntity as rb1
where (anfrage0.sparte.i18nKey = rb1.key) and (rb1.language = 'de')
) asc
我的Java代码如下所示:
private List<AnfrageDTO> getAnfragen() {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<AnfrageDTO> query = cb.createQuery(AnfrageDTO.class);
Root<Anfrage> anfrage = query.from(Anfrage.class);
anfrage.join(Anfrage_.sparte, JoinType.LEFT);
query.select(cb.construct(AnfrageDTO.class,
anfrage.get(Anfrage_.id),
anfrage.get(Anfrage_.name),
anfrage.get(Anfrage_.sparte).get(Sparte_.id),
anfrage.get(Anfrage_.sparte).get(Sparte_.i18nKey),
// create subquery for translated sparte.i18nKey
createResourceBundleSubQuery(cb, query, anfrage.get(Anfrage_.sparte).get(Sparte_.i18nKey)).getSelection()));
TypedQuery<AnfrageDTO> tq = entityManager
.createQuery(query)
// use subquery to sort by translated sparte.i18nKey
.orderBy(cb.asc(createResourceBundleSubQuery(cb, query, anfrage.get(Anfrage_.sparte).get(Sparte_.i18nKey))));
tq.setMaxResults(10);
List<AnfrageDTO> anfragen = tq.getResultList();
return anfragen;
}
public Subquery<String> createResourceBundleSubQuery(CriteriaBuilder cb, CriteriaQuery<?> query, <String> expr) {
Subquery<String> subquery = query.subquery(String.class);
Root<ResourceBundleEntity> rb = subquery.from(ResourceBundleEntity.class);
subquery
.select(rb.get(ResourceBundleEntity_.value))
.where(cb.and(
cb.equal(expr, rb.get(ResourceBundleEntity_.key)),
cb.equal(rb.get(ResourceBundleEntity_.language), "de")));
return subquery;
}
在本机SQL查询中使用别名也可以正常工作
select distinct
anfrage0_.id,
anfrage0_.name,
anfrage0_.sparte_id,
sparte4_.i18n_key,
(select rb3.i18n_value from resource_bundle rb3 where rb3.language_code = 'de' and rb3.i18n_key = sparte4_.i18n_key) as sparte_i18n_value
from
mis2.anfrage anfrage0_
left outer join mis2.sparte sparte4_ on anfrage0_.sparte_id = sparte4_.id
order by (
select rb.i18n_value
from mis2.resource_bundle rb
where sparte4_.i18n_key = rb.i18n_key and rb.language_code = 'de'
) asc
select distinct
anfrage0_.id,
anfrage0_.name,
anfrage0_.sparte_id,
sparte4_.i18n_key,
(select rb3.i18n_value from resource_bundle rb3 where rb3.language_code = 'de' and rb3.i18n_key = sparte4_.i18n_key) as sparte_i18n_value
from
mis2.anfrage anfrage0_
left outer join mis2.sparte sparte4_ on anfrage0_.sparte_id = sparte4_.id
order by sparte_i18n_value
asc
如果JPA标准API支持在orderBy子句中使用别名,那就太好了
任何提示欢迎-谢谢
我的环境是WildFly 11和PostgreSQL 9.6。JPA不支持在order by子句中传递参数,您的问题以前被问过:他使用的是子查询,而不是order子句中的参数。JPA规范除了WHERE/HAVING子句外,没有指定它们在何处使用。是的,但它是一个子查询。是的,子查询和参数都使ORDER子句在查询中动态,JPA不支持它。答案取决于使用的JPA提供程序。根据使用Hibernate生成的SQL判断。JPA规范没有在ORDER子句中指定子查询的使用。一些JPA提供商(如DataNucleus)确实允许这样做,但您的提供商似乎不允许这样做。