CriteriaBuilder.construct-DTO投影

时间:2019-07-02 21:45:37

标签: java spring spring-boot spring-data-jpa

我正在制作一个包含两个以上DTO的DTO报告对象,如下所示:

@Getter
@Setter
@ToString
@AllArgsConstructor
@Accessors(chain = true)
public class ReportDTO implements Serializable {

    private Transaction transaction;

    private Payment payment;

    @Getter
    @Setter
    @ToString
    @AllArgsConstructor
    @Accessors(chain = true)
    public static class Transaction implements Serializable {

        private Long id;

        private TransactionStatus status;

        private String currency;

        private BigDecimal total;
    }

    @Getter
    @Setter
    @ToString
    @AllArgsConstructor
    @Accessors(chain = true)
    public static class Payment implements Serializable {

        private Long tid;

        private String currency;

        private BigDecimal total;
    }
}

我尝试使用CriteriaQuery api填充它,就像这样:

public <T extends Transaction> List<ReportDTO> generateReport(final Specification<T> specification, Class<T> classx) {

        CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
        CriteriaQuery<ReportDTO> criteriaQuery = criteriaBuilder.createQuery(ReportDTO.class);

        Root<T> root = criteriaQuery.from(classx);
        criteriaQuery.select(criteriaBuilder.construct(
                ReportDTO.class,
                criteriaBuilder.construct(
                        ReportDTO.Transaction.class,
                        root.get("id"),
                        root.get("status"),
                        root.get("currency"),
                        root.get("total")
                ),
                criteriaBuilder.construct(
                        ReportDTO.Payment.class,
                        root.get("payment").get("tid"),
                        root.get("currency"),
                        root.get("payment").get("amount")
                )
        ));

        criteriaQuery.where(specification.toPredicate(root, criteriaQuery, criteriaBuilder));
        criteriaQuery.orderBy(criteriaBuilder.desc(root.get("date")));
        TypedQuery<ReportDTO> typedQuery = this.entityManager.createQuery(criteriaQuery);

        return typedQuery.getResultList();
    }

但是...显然,我不能在另一个criteriaBuilder.construct中使用criteriaBuilder.construct ...

这是部分异常输出:

org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: new near line 1, column XX [select new com.demo.ReportDTO(new com.demo.ReportDTO$Transaction(generatedAlias0.id, generatedAlias0.status, generatedAlias0.currency, generatedAlias0.total)) from com.demo.Transactions as generatedAlias0 where generatedAlias0.date between :param0 and :param1 order by generatedAlias0.date desc]
    at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:91) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:288) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:187) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:142) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:302) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:240) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1894) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:531) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.criteria.CriteriaQueryImpl$1.buildCompiledQuery(CriteriaQueryImpl.java:316) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.criteria.compile.CriteriaCompiler.compile(CriteriaCompiler.java:130) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:699) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:347) ~[spring-orm-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at com.sun.proxy.$Proxy141.createQuery(Unknown Source) ~[na:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298) ~[spring-orm-4.3.10.RELEASE.jar:4.3.10.RELEASE]

我想知道是否可以使用Criteria API进行填充。

我已经成功地将所有内部属性放到ReportDTO上,但是那样对我来说看起来更加干净。

0 个答案:

没有答案