【问题标题】:JPA 2.1 criteria API: Using subselects in orderByJPA 2.1 标准 API:在 orderBy 中使用子选择
【发布时间】:2016-01-25 15:44:08
【问题描述】:

我试图在子查询的帮助下对我的查询进行排序,但总是得到一个

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.hql.internal.ast.QuerySyntaxException:意外的 AST 节点

例如

@Entity
@Table
public class Product extends AbstractEntity {
     @OneToMany(mappedBy = "product")
     private List<Item> items = new ArrayList<>();
}

@Entity
public class Item extends AbstractEntity {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "product_id")
    private Product product;

    @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
    @Column(name = "delivery_date")
    private DateTime deliveryDate;
}

我想查询所有产品并按其商品的最早交货日期订购结果。我构建查询如下:

CriteriaBuilder builder = manager.getCriteriaBuilder();
CriteriaQuery<Product> query = builder.createQuery(Product.class);
Root<Product> product = query.from(Product.class);

Subquery<DateTime> deliveryDateSQ = query.subquery(DateTime.class);
Root<Item> itemsFrom = deliveryDateSQ.from(Item.class);
deliveryDateSQ.select(
    criteriaBuilder.least(itemsFrom.get(Item_.deliveryDate)));
deliveryDateSQ.where(
    criteriaBuilder.equal(itemsFrom.get(Item_.product), product));

query.orderBy(criteriaBuilder.asc(deliveryDateSQ));

TypedQuery<Product> typedQuery = manager.createQuery(query);

执行查询时总是出现以下错误:

antlr.NoViableAltException: unexpected AST node: query
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.orderExpr(HqlSqlBaseWalker.java:1836) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.orderExprs(HqlSqlBaseWalker.java:1627) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.orderClause(HqlSqlBaseWalker.java:1603) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:642) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:249) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]

还有一些来自 Spring 的更多细节:

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node: query [...]
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:381)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:216)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)

有没有办法以某种方式更改查询以使其按预期工作?

感谢您的帮助。

【问题讨论】:

    标签: java spring hibernate jpa criteria-api


    【解决方案1】:

    我们可以使用 @OrderBy(clause = "delivery_date ASC") Hibernate 子句。

    所以你的模型可以是这样的。

    @Entity
    @Table
    public class Product extends AbstractEntity {
         @OrderBy(clause = "delivery_date ASC")
         @OneToMany(mappedBy = "product")
         private List<Item> items = new ArrayList<>();
    }
    
    @Entity
    public class Item extends AbstractEntity {
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "product_id")
        private Product product;
    
        @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
        @Column(name = "delivery_date")
        private DateTime deliveryDate;
    }
    

    【讨论】:

    • 但这仅订购产品中的项目。我想要做的是在他们的项目的earlies delivery_date 之前订购所有产品。
    猜你喜欢
    • 2014-07-13
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 2011-03-29
    • 2016-02-05
    • 2016-05-31
    • 2017-04-18
    • 1970-01-01
    相关资源
    最近更新 更多