Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » JPA-RS problem: java.lang.ClassCastException: java.util.ArrayList cannot be cast...(java.lang.ClassCastException: java.util.ArrayList cannot be cast to org.eclipse.persistence.internal.descriptors.PersistenceObject)
icon5.gif  JPA-RS problem: java.lang.ClassCastException: java.util.ArrayList cannot be cast... [message #1007121] Mon, 04 February 2013 14:29 Go to next message
Daniel Szalay is currently offline Daniel SzalayFriend
Messages: 15
Registered: February 2013
Junior Member
Hi! I successfully set up a web application with EclipseLink 2.4.1 and JPA-RS on GlassFish 3.1.2.2. I can retrieve data through the GET method as described in the EclipseLink WIKI, however I have problems with the PUT operations.

Here is my entity class:

@Entity
public class UserTable implements Serializable {
	
	@Id
	@GeneratedValue
	private long id;
	@Column
	private String userId;
	@OneToMany(mappedBy="table", orphanRemoval=true, cascade=CascadeType.ALL)
	private List<TimeRow> rows;
	
	public UserTable() {
		this.rows = new ArrayList<TimeRow>();
	}

	public UserTable(String userId, List<TimeRow> rows) {
		this.userId = userId;
		this.rows = rows;
	}
}


I want to create a new UserTable entity with a PUT request using the URL "/persistence/unit/entity/UserTable", and the request body:

[
    {
        "userId": "testuser"
    }
]


Here is the response:

Quote:
The server encountered an internal error () that prevented it from fulfilling this request. javax.servlet.ServletException: java.lang.ClassCastException: java.util.ArrayList cannot be cast to org.eclipse.persistence.internal.descriptors.PersistenceObject.


Am I doing something wrong? Maybe the request body should be syntactically different? I would expect that I don't have to specify an id (@GeneratedValue), neither the fields that are initialized in the constructor.

I've read in an article that: Quote:
The last step is to set the Persistence Units to Local Resource instead of JTA Datasource, else it won't work.


I didn't find any evidence in the EclipseLink docs to prove this. My unit is defined to use 'JTA'; is this a problem?

[Updated on: Tue, 05 February 2013 12:18]

Report message to a moderator

Re: JPA-RS problem: java.lang.ClassCastException: java.util.ArrayList cannot be cast... [message #1007360 is a reply to message #1007121] Tue, 05 February 2013 15:46 Go to previous messageGo to next message
James Sutherland is currently offline James SutherlandFriend
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

Enable logging on the server and include the log and full exception stack trace.


James : Wiki : Book : Blog : Twitter
Re: JPA-RS problem: java.lang.ClassCastException: java.util.ArrayList cannot be cast... [message #1007537 is a reply to message #1007360] Wed, 06 February 2013 10:57 Go to previous messageGo to next message
Daniel Szalay is currently offline Daniel SzalayFriend
Messages: 15
Registered: February 2013
Junior Member
Now I am using EclipseLink 3.4.2, and tried it with the following simple entity class without relationships:

@Entity
@NamedQueries({
    @NamedQuery(name="Test.findAll",
                query="SELECT t FROM Test t")
}) 
public class Test implements Serializable {
	
	@Id
	@GeneratedValue
	private long id;
	@Column
	private String userId;
	@Column
	private List<String> names;

}


The ClassCastException occurs when I define the object wrapped inside [] brackets. I have tried to use the PUT method with the following request bodies:

{
    "id": 1,
    "userId": "TEST",
    "names": ["one","two"]
}


The previous is executed successfully. I would expect that I don't have to specify the id field, since it is a @GeneratedValue, however for this request body:

{
    "userId": "TEST",
    "names": ["one","two"]
}


i get this response:

Quote:
400 - Bad Request The request sent by the client was syntactically incorrect (Bad Request).


What am I doing wrong? Is this the normal behavior?

[Updated on: Wed, 06 February 2013 16:21]

Report message to a moderator

Re: JPA-RS problem: java.lang.ClassCastException: java.util.ArrayList cannot be cast... [message #1007705 is a reply to message #1007537] Thu, 07 February 2013 08:21 Go to previous messageGo to next message
Daniel Szalay is currently offline Daniel SzalayFriend
Messages: 15
Registered: February 2013
Junior Member
Okay, I've found the reason in EclipseLink/Release/2.4.0/JPA-RS/REST-API:

Quote:
PUT is required to be idempotent. As a result, it will fail if called with an object that expects the server to provide an ID field. Typically this will occur if the metadata specifies a generated key and the field that contains that key is unpopulated.


Still, my question is: what is the best practice in this case? Providing a web service that returns an available id? This would lead straight to the TOCTOU problem, except if it is backed up by a bean that never gives out the same ID twice and has an ID pool for every entity type.

Also, I am confused that PUT is defined as PERSIST, and POST is defined as MERGE. So with POST I don't have to specify the ID? Couldn't really get POST working unfortunately.

[Updated on: Thu, 07 February 2013 13:11]

Report message to a moderator

Re: JPA-RS problem: java.lang.ClassCastException: java.util.ArrayList cannot be cast... [message #1007785 is a reply to message #1007705] Thu, 07 February 2013 13:53 Go to previous messageGo to next message
Daniel Szalay is currently offline Daniel SzalayFriend
Messages: 15
Registered: February 2013
Junior Member
Exception thrown when trying to POST Test entity:

StandardWrapperValve[org.eclipse.persistence.jpa.rs.service.JPARSApplication]: PWC1406: Servlet.service() for servlet org.eclipse.persistence.jpa.rs.service.JPARSApplication threw exception java.lang.NullPointerException at org.eclipse.persistence.jpa.rs.util.StreamingOutputMarshaller.mediaType(StreamingOutputMarshaller.java:118) at org.eclipse.persistence.jpa.rs.EntityResource.update(EntityResource.java:170) at org.eclipse.persistence.jpa.rs.EntityResource.update(EntityResource.java:157) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60) at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205) at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288) at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108) at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469) at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339) at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:708) at javax.servlet.http.HttpServlet.service(HttpServlet.java:770) at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231) at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195) at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860) at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757) at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056) at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229) at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) at com.sun.grizzly.ContextTask.run(ContextTask.java:71) at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) at java.lang.Thread.run(Thread.java:662)
Re: JPA-RS problem: java.lang.ClassCastException: java.util.ArrayList cannot be cast... [message #1011629 is a reply to message #1007785] Tue, 19 February 2013 23:24 Go to previous messageGo to next message
Gul Onural is currently offline Gul OnuralFriend
Messages: 12
Registered: February 2013
Junior Member
Hi Daniel,

Is it possible to upgrade to the latest version of eclipselink from nightly? I noticed that you are using eclipselink 2.4.1 and since then we have fixed many bugs in JPA- RS.

Answer to your question about PUT and POST: PUT has to be idempotent, meaning that PUT can be applied multiple times without changing the result beyond the initial application. Since your object is annotated @GeneratedValue, its id is expected to be generated by eclipselink on the server side. So, PUT will fail if called with an object that expects the server to provide an ID. You should be using POST and should not provide an ID in the request.



Re: JPA-RS problem: java.lang.ClassCastException: java.util.ArrayList cannot be cast... [message #1011925 is a reply to message #1007785] Wed, 20 February 2013 14:22 Go to previous messageGo to next message
Gul Onural is currently offline Gul OnuralFriend
Messages: 12
Registered: February 2013
Junior Member
Hi Daniel,

Is it possible to upgrade your eclipselink and jpa-rs jars to latest ? Recently, we have submitted large number of fixes to this area.
Re: JPA-RS problem: java.lang.ClassCastException: java.util.ArrayList cannot be cast... [message #1012854 is a reply to message #1011925] Fri, 22 February 2013 10:37 Go to previous messageGo to next message
Daniel Szalay is currently offline Daniel SzalayFriend
Messages: 15
Registered: February 2013
Junior Member
Thanks for your response! I updated EclipseLink to 'eclipselink-2.5.0.v20130220-795a5ad' (nightly). Now, both POST and PUT result in this error message:

Quote:

HTTP Status 415 - Unsupported Media Type

The server refused this request because the request entity is in a format not supported by the requested resource for the requested method (Unsupported Media Type).


Accept: application/json
is set in header.

UPDATE

Okay, I changed the header to
Content-Type: application/json
and now it seems to work.

Now I would expect that I should use POST to insert an entity and use PUT to update an entity. Is that right? At the moment I can do both with POST, but PUT throws an internal server error (HTTP code 500):

Quote:

org.eclipse.persistence.exceptions.TransactionException
Exception Description: Error committing externally managed transaction


Where the request body is:

{
"id": 1,
"userId":"test",
"names":["one","two","three"]
}


Are there examples/tutorials out there which explain how to convert the retrieved data back to object instances? I tried to do so with Jackson, but it cannot consume the "_relationships" attribute.

[Updated on: Wed, 27 February 2013 15:58]

Report message to a moderator

Re: JPA-RS problem: java.lang.ClassCastException: java.util.ArrayList cannot be cast... [message #1015203 is a reply to message #1012854] Wed, 27 February 2013 17:50 Go to previous messageGo to next message
Gul Onural is currently offline Gul OnuralFriend
Messages: 12
Registered: February 2013
Junior Member
You can use PUT to create an entity, but you must supply the id of the entity, because PUT is idempotent.
If you want to use generated ids (generated ids by JPA), then you use POST, but in this case do not provide id for the entity.
Re: JPA-RS problem: java.lang.ClassCastException: java.util.ArrayList cannot be cast... [message #1015269 is a reply to message #1015203] Thu, 28 February 2013 00:36 Go to previous messageGo to next message
Gul Onural is currently offline Gul OnuralFriend
Messages: 12
Registered: February 2013
Junior Member
In terms of unmarshalling responses you get from JPA-RS, here are couple of options :

- Use eclipselink moxy and write your own XMLAdapter for unmarshaling response, see examples here :
blog.bdoughan.com/2010/07/xmladapter-jaxbs-secret-weapon.html]
or here :
www.eclipse.org/eclipselink/documentation/2.4/moxy/advanced_concepts006.htm]

- Use Jersey client, see section 3.3. Ease of use and reusing JAX-RS artifacts from the link below for some examples :
jersey.java.net/nonav/documentation/latest/user-guide.html]
Re: JPA-RS problem: java.lang.ClassCastException: java.util.ArrayList cannot be cast... [message #1015342 is a reply to message #1015269] Thu, 28 February 2013 09:47 Go to previous message
Daniel Szalay is currently offline Daniel SzalayFriend
Messages: 15
Registered: February 2013
Junior Member
Thank you very much for helping me!!! Smile
Previous Topic:ClassWeaver generates buggy code ?
Next Topic:A non-read-only mapping must be defined for the sequence number field
Goto Forum:
  


Current Time: Thu Nov 27 08:51:35 GMT 2014

Powered by FUDForum. Page generated in 0.31790 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software