JPA 2构造函数表达式不能使用构造函数

时间:2014-01-31 08:11:18

标签: java constructor jpa-2.0

我在WebSphere Application Server 8上使用OpenJPA 2.1.1。

我想使用构造函数表达式从SELECT查询创建对象:

String queryString = "SELECT NEW mypackage.StatisticDataObject(c.source, "
    + "SUM(CASE WHEN (c.validTo <= CURRENT_TIMESTAMP AND c.expireNoProblem LIKE 'N') THEN 1 ELSE 0 END ), "
    + "SUM(CASE WHEN (c.validTo <= CURRENT_TIMESTAMP AND c.expireNoProblem LIKE 'Y') THEN 1 ELSE 0 END ), "
    + "SUM(CASE WHEN (c.validTo > :timestamp30 ) THEN 1 ELSE 0 END ), "
    + "SUM(CASE WHEN (c.validTo > :timestamp10 AND c.validTo <= :timestamp30 ) THEN 1 ELSE 0 END ), "
    + "SUM(CASE WHEN (c.validTo > CURRENT_TIMESTAMP AND c.validTo <= :timestamp10 ) THEN 1 ELSE 0 END ) )"
    + "FROM MYTABLE c GROUP BY c.source";
TypedQuery<StatisticDataObject> q = em.createQuery(queryString,
                StatisticDataObject.class);
q.setParameter("timestamp30", getTimestampIn(30));
q.setParameter("timestamp10", getTimestampIn(10));

构造

public StatisticDataObject(String name, Integer expired,
        Integer expiredButOK, Integer expireIn10Days, Integer expireIn30Days,
        Integer expireGT30Days) {
    this.name = name;
    this.expired = expired;
    this.expiredButOK = expiredButOK;
    this.expireIn10Days = expireIn10Days;
    this.expireIn30Days = expireIn30Days;
    this.expireGT30Days = expireGT30Days;
}

但我得到以下例外:

Caused by: <openjpa-2.1.1-SNAPSHOT-r422266:1141200 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: Query "SELECT NEW mypackage StatisticDataObject(c.source, ... at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:872)
    at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:794)
    at org.apache.openjpa.kernel.DelegatingQuery.execute(DelegatingQuery.java:542)
    at org.apache.openjpa.persistence.QueryImpl.execute(QueryImpl.java:315)
    at org.apache.openjpa.persistence.QueryImpl.getResultList(QueryImpl.java:331)
...
Caused by: java.lang.RuntimeException: Es wurde kein Konstruktor für "class mypackage.StatisticDataObject" mit den Argumenttypen "[class java.lang.String, class java.lang.String, class java.lang.String, class java.lang.String, class java.lang.String, class java.lang.String]" gefunden, um die Daten einzutragen. 
// ENGLISH Translation: Caused by: java.lang.RuntimeException: There is no constructor "class mypackage.StatisticDataObject" with argument type "[class java.lang.String, class java.lang.String, class java.lang.String, class java.lang.String, class java.lang.String, class java.lang.String]".
    at org.apache.openjpa.kernel.FillStrategy$NewInstance.findConstructor(FillStrategy.java:139)
    at org.apache.openjpa.kernel.FillStrategy$NewInstance.fill(FillStrategy.java:144)
    at org.apache.openjpa.kernel.ResultShape.pack(ResultShape.java:362)
    at org.apache.openjpa.kernel.ResultShapePacker.pack(ResultShapePacker.java:48)
    at org.apache.openjpa.kernel.QueryImpl$PackingResultObjectProvider.getResultObject(QueryImpl.java:2082)
    at org.apache.openjpa.lib.rop.EagerResultList.<init>(EagerResultList.java:36)
    at org.apache.openjpa.kernel.QueryImpl.toResult(QueryImpl.java:1251)
    at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:1007)
    at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:863)
    ... 84 more

如果我在没有NEW mypackage.StatisticDataObject()的情况下运行查询,它将使用Object []。对象[1-5](.getClass())的类也是Integer。

那么为什么JPA在使用构造函数表达式时会从SUM()而不是Integer返回一个String?

1 个答案:

答案 0 :(得分:0)

在构造函数中,请记住要应用 SUM 的字段类型的状态需要是数字,并且结果类型必须与字段类型相对应。例如,如果将Double字段求和,则结果将返回Double。如果对Long字段类型求和,则响应将以Long形式返回。

这是问题的根本原因,SUM不返回Integer类型。