我正在制作一个包含两个以上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上,但是那样对我来说看起来更加干净。