使用带有datanucleus和app引擎的日期的类强制转换异常(GAE Java)

时间:2014-02-11 13:36:51

标签: java google-app-engine jpa datanucleus

我有一个我在GAE上运行的应用程序,使用JPA访问数据存储区。

我在尝试检索时,在我的一个实体类型上遇到了类强制转换异常。例外是:

Caused by: java.lang.ClassCastException: org.datanucleus.store.types.sco.simple.Date cannot be cast to java.lang.Long
    at com.annkh.entities.PurchasedQuote.jdoReplaceField(PurchasedQuote.java)
    at org.datanucleus.state.AbstractStateManager.replaceField(AbstractStateManager.java:2387)
    at org.datanucleus.state.JDOStateManager.replaceField(JDOStateManager.java:1877)
    at org.datanucleus.state.JDOStateManager.replaceField(JDOStateManager.java:1781)
    at org.datanucleus.store.types.sco.SCOUtils.createSCOWrapper(SCOUtils.java:241)
    at org.datanucleus.store.types.sco.SCOUtils.newSCOInstance(SCOUtils.java:139)
    at org.datanucleus.state.JDOStateManager.wrapSCOField(JDOStateManager.java:2230)
    at com.google.appengine.datanucleus.FetchFieldManager.fetchFieldFromEntity(FetchFieldManager.java:468)
    at com.google.appengine.datanucleus.FetchFieldManager.fetchObjectField(FetchFieldManager.java:408)
    at org.datanucleus.state.AbstractStateManager.replacingObjectField(AbstractStateManager.java:2353)
    at com.annkh.entities.PurchasedQuote.jdoReplaceField(PurchasedQuote.java)
    at com.annkh.entities.PurchasedQuote.jdoReplaceFields(PurchasedQuote.java)
    at org.datanucleus.state.JDOStateManager.replaceFields(JDOStateManager.java:1935)
    at org.datanucleus.state.JDOStateManager.replaceFields(JDOStateManager.java:1962)
    at com.google.appengine.datanucleus.EntityUtils$1.fetchFields(EntityUtils.java:974)
    at org.datanucleus.state.JDOStateManager.loadFieldValues(JDOStateManager.java:764)
    at org.datanucleus.state.JDOStateManager.initialiseForHollow(JDOStateManager.java:205)
    at org.datanucleus.state.StateManagerFactory.newForHollowPopulated(StateManagerFactory.java:89)
    at org.datanucleus.state.ObjectProviderFactory.newForHollowPopulated(ObjectProviderFactory.java:75)
    at org.datanucleus.ObjectManagerImpl.findObject(ObjectManagerImpl.java:2882)
    at com.google.appengine.datanucleus.EntityUtils.entityToPojo(EntityUtils.java:1014)
    at com.google.appengine.datanucleus.query.DatastoreQuery$2.apply(DatastoreQuery.java:229)
    at com.google.appengine.datanucleus.query.DatastoreQuery$2.apply(DatastoreQuery.java:226)
    at com.google.appengine.datanucleus.query.LazyResult.resolveNext(LazyResult.java:96)
    at com.google.appengine.datanucleus.query.LazyResult.resolveAll(LazyResult.java:121)
    at com.google.appengine.datanucleus.query.LazyResult.size(LazyResult.java:115)
    at com.google.appengine.datanucleus.query.StreamingQueryResult.size(StreamingQueryResult.java:151)
    at com.annkh.resources.MIResource.countPurchases(MIResource.java:67)
    at com.annkh.resources.MIResource.articlesListView(MIResource.java:60)

该实体有一个简单的java.util.Date字段,名为datePurchased,似乎导致了这个问题:

import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.io.Serializable;
import java.util.Date;

import static javax.persistence.GenerationType.IDENTITY;

@SuppressWarnings("serial")
@Entity
public class PurchasedQuote implements Serializable {
    @Id
    @GeneratedValue(strategy = IDENTITY)
    protected Long id;
    <blah blah other fields>

    @Basic
    protected java.util.Date datePurchased;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }


    public java.util.Date getDatePurchased() {
        return datePurchased;
    }

    public void setDatePurchased(Date datePurchased) {
        this.datePurchased = datePurchased;
    }
}

导致错误的调用是一个简单的检索问题:

List<PurchasedQuote> quotes = purchaseDAO.findAll();
map.put("purchaseCount", quotes.size());

在appengine数据查看器中,日期与其他正常工作的对象中的其他日期没有什么不同。数据存储区查看器中字段的类型为gd:when。

我已经尝试过在其他答案中提出的技巧(包装和解包调用get和使用返回纯java.util.Date的方法设置),但似乎没有任何帮助。任何建议,将不胜感激。

2 个答案:

答案 0 :(得分:1)

这不是列/字段datePurchased的问题。相反,您的其他字段(在您的代码中<blah blah other fields>下)存在问题,其中您的Long字段之一被错误地映射到date类型列。只需逐个检查字段和映射。为了您的信息,如果您没有为字段指定列名,那么它将假定字段名称默认为列名。例如:

private String testCol;
// by default it assumes the column name as testCol

答案 1 :(得分:0)

事实证明我忘记了类中Text字段的@Basic注释。这导致非常奇怪的行为,包括显示的错误。日期字段没有任何问题。