2

I get a ClassCastException when assigning an object from JPA to an attribute of a ManagedBean:

Object r = query.getSingleResult(); // javax.persistence.Query
ClassLoader c1 = this.getClass().getClassLoader();
ClassLoader c2 = r.getClass().getClassLoader();
user = (User) r; // blubb.model.User

The problem is that c1 (ManagedBean) and c2 (EclipseLink) are different ClassLoaders:

c1: WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
c2: WebappClassLoader (delegate=true)

How can I fix this?

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
voglerr
  • 713
  • 2
  • 9
  • 17
  • Why are the classes loaded with two different class loaders? – Edwin Dalorzo Apr 14 '11 at 14:54
  • That's what I ask myself too. I don't specify anything about ClassLoaders. – voglerr Apr 14 '11 at 15:22
  • Nonetheless, you are are sure the Object r is of type User, right? I mean, if you println r.getClass(), it is a User, correct? – Edwin Dalorzo Apr 14 '11 at 15:24
  • Yes, same Class, different ClassLoader - that's why the cast fails. – voglerr Apr 14 '11 at 15:25
  • Have you tried wrapping `query.getSingleResult()` into a method that uses generics and assign directly? Well... probably you will get the same runtime exception. But it's good for abstraction and less coupling. – bluefoot Apr 14 '11 at 15:26
  • Yes, tried it. Also tried createQuery(String, Class). Same problem. – voglerr Apr 14 '11 at 15:28
  • Well, a good start is find out why you have two different class loaders with different versions of the class User. Another thing we need to know is if the two class loaders are related. You can print the hierarchy of class loaders in a loop using ClassLoader.getParent() until you reach the bootstrap class loader(i.e. parent == null). If you do the same with both class loaders we can determine in which point they are related. – Edwin Dalorzo Apr 14 '11 at 15:31
  • Maybe [these answers](http://stackoverflow.com/questions/826319/classcastexception-when-casting-to-the-same-class) can help you. – Matt Handy Apr 14 '11 at 17:30

2 Answers2

2

What is your environment? Are you using Java EE, Spring, OSGi? Which server, WLS, WAS, GF?

Did you redeploy your application? Is the persistence unit managed or non-managed?

It could be that you redeployed your application, but never closed the EntityManagerFactory, so it is still deployed with the old classes.

James
  • 19,367
  • 9
  • 72
  • 129
  • JSF with EclipseLink and PrimeFaces on GlassFish. You're right, I only get the error sometimes after redeploying. – voglerr Apr 19 '11 at 12:06
0

I've had same problem. Simple JSF project with EclipseLink 2.5.2 JPA inside of Glassfish 4.1.1.

Solved by correctly closing the EntityManagerFactory. I reccomend to use ServletContextListener (@WebListener) (take look here or here).

Community
  • 1
  • 1
martlin
  • 121
  • 1
  • 8