jpa ClassCastException Long无法强制转换为List

时间:2014-02-27 09:56:35

标签: java list google-app-engine jpa

我正在开发一个关于gae / j的应用程序。

我有一个实体设置,我试图坚持列表的字段。问题是我得到了ClassCastException。

@Entity
public class Party {

@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
public Key Id;


@ElementCollection(fetch = FetchType.EAGER)
public List<Long> guests;

public List<Long> getGuests(){
    if(guests== null){
        guests = new ArrayList<Long>();
    }
    return guests;
}

public void setGuests(List<Long> guests){
    this.guests = guests;
}
}

当我测试代码时,我在堆栈跟踪中收到此错误。

com.google.api.server.spi.SystemService invokeServiceMethod: java.lang.Long cannot be cast to java.util.List
java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.List
    at com.google.appengine.datanucleus.TypeConversionUtils.datastoreValueToPojoCollection(TypeConversionUtils.java:456)
    at com.google.appengine.datanucleus.TypeConversionUtils.datastoreValueToPojoValue(TypeConversionUtils.java:377)
    at com.google.appengine.datanucleus.FetchFieldManager.fetchFieldFromEntity(FetchFieldManager.java:463)
    at com.google.appengine.datanucleus.FetchFieldManager.fetchObjectField(FetchFieldManager.java:408)
    at org.datanucleus.state.AbstractStateManager.replacingObjectField(AbstractStateManager.java:2353)
    at com.mastermindcode.theincrowd.Party.jdoReplaceField(Party.java)
    at com.mastermindcode.theincrowd.Party.jdoReplaceFields(Party.java)
    at org.datanucleus.state.JDOStateManager.replaceFields(JDOStateManager.java:1935)
    at org.datanucleus.state.JDOStateManager.replaceFields(JDOStateManager.java:1962)
    at com.google.appengine.datanucleus.DatastorePersistenceHandler.fetchObject(DatastorePersistenceHandler.java:567)
    at org.datanucleus.state.JDOStateManager.loadFieldsFromDatastore(JDOStateManager.java:1638)
    at org.datanucleus.state.JDOStateManager.loadUnloadedFieldsInFetchPlan(JDOStateManager.java:1363)
    at org.datanucleus.state.JDOStateManager.detach(JDOStateManager.java:2718)
    at org.datanucleus.ObjectManagerImpl.performDetachOnCloseWork(ObjectManagerImpl.java:4571)
    at org.datanucleus.ObjectManagerImpl.performDetachOnClose(ObjectManagerImpl.java:4534)
    at org.datanucleus.ObjectManagerImpl.close(ObjectManagerImpl.java:1105)
    at org.datanucleus.api.jpa.JPAEntityManager.close(JPAEntityManager.java:193)
    at com.mastermindcode.theincrowd.PartyEndpoint.listParty(PartyEndpoint.java:104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:45)
    at com.google.api.server.spi.SystemService.invokeServiceMethod(SystemService.java:359)
    at com.google.api.server.spi.SystemServiceServlet.execute(SystemServiceServlet.java:124)
    at com.google.api.server.spi.SystemServiceServlet.doPost(SystemServiceServlet.java:82)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:437)
    at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:444)
    at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:188)
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:308)
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:300)
    at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:441)
    at java.lang.Thread.run(Thread.java:724)

我很抱歉,如果有一个我忽略的简单答案,但我想要做的就是在聚会对象的列表字段中存储用户ID列表(类型为Long)。我已经尝试了每个jpa注释并阅读了应用程序引擎文档几天寻找解决方案。

我通常可以找到我的bug查看堆栈跟踪,但是这个没有告诉我代码中的bug在哪里。如果您在第104行注意到Partyendpoint.java中导致的问题,那么它就是实体管理器关闭的地方。

感谢您的帮助......

更新:我添加了我正在调用的导致问题的方法。我正在使用云端点向android和ios设备发送集合响应。

@SuppressWarnings({ "unchecked", "unused" })
@ApiMethod(name = "listParty")
public CollectionResponse<Party> listParty(@Nullable @Named("cursor") String cursorString,@Nullable @Named("limit") Integer limit) {

    EntityManager mgr = null;
    Cursor cursor = null;
    List<Party> execute = null;

    try {
        mgr = getEntityManager();
        Query query = mgr.createQuery("select from Party as Party");
        if (cursorString != null && cursorString != "") {
            cursor = Cursor.fromWebSafeString(cursorString);
            query.setHint(JPACursorHelper.CURSOR_HINT, cursor);
        }

        if (limit != null) {
            query.setFirstResult(0);
            query.setMaxResults(limit);
        }

        execute = (List<Party>) query.getResultList();
        cursor = JPACursorHelper.getCursor(execute);
        if (cursor != null)
            cursorString = cursor.toWebSafeString();

        // Tight loop for fetching all entities from datastore and accomodate
        // for lazy fetch.
        for (Party obj : execute)
            ;
    } finally {
        mgr.close();
    }

    return CollectionResponse.<Party> builder().setItems(execute)
            .setNextPageToken(cursorString).build();
}

1 个答案:

答案 0 :(得分:2)

您可能正在从代码中进行计数查询并将结果转换为L ist<>,因此您将面临错误。

以下是使用EntityManager获取计数值的方法(您也可以使用Session)。

Long count = (Long)em.createQuery("SELECT COUNT(d) FROM Test d").getSingleResult();

Long count = em.createQuery("SELECT COUNT(d) FROM Test d", Long.class).getSingleResult();