kreshendo
kreshendo

Reputation: 384

jpa ClassCastException Long cannot be cast to List

I am developing an application on gae/j.

I have an entity set up and i'm trying to persist a field of List. the problem is i get a 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;
}
}

When I test the code I receive this error in the stack trace.

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)

I'm sorry if there is a simple answer I am overlooking but all I want to do is store a list of user id's (type Long) in a list field on the party object. I have tried every jpa annotation and read over the app engine documentation for days looking for the solution to this.

I can normally find my bugs looking at the stack trace but this one doesn't tell me where the bug is in the code. If you notice the problem caused in Partyendpoint.java at line 104, it is where the entity manager is closed.

Thanks for any help....

Update: I added the method I am calling that is causing the issue. I'm using cloud endpoints to send a collection response to android and ios devices.

@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();
}

Upvotes: 0

Views: 1532

Answers (1)

Sabuj Hassan
Sabuj Hassan

Reputation: 39395

Possibly you are doing count query from your code and taking the result into a List<> and hence you are facing the error.

Here is how you can get the value of count using EntityManager(You can use the Session as well).

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

or

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

Upvotes: 2

Related Questions