Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ClassCastException in JPA Entitiy after redeploy (Glassfish 3.1.2)

I have a strange effect when undeploying and deploying a WebArchive (.war) with Glassfish 3.1.2.

$ asadmin undeploy myWebApp; asadmin deploy target/myWebApp.war

It deploys normally, but when I fetch an entity bean via the entity manager, it throws an Exception: [#|2012-12-11T15:26:09.772+0100|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=119;_ThreadName=Thread-2;|java.lang.ClassCastException: org.YourEntity cannot be cast to org.YourEntity

The exception is thrown in the q.getSingleResult() call.

  @PersistenceContext(unitName = "org.my-PU")
  private EntityManager em = Persistence.createEntityManagerFactory("org.my-PU").createEntityManager();
  ...
  public YourEntity findYourEntity() throws Exception {
      TypedQuery<YourEntity> q = em.createQuery("select ye from YourEntity ye", 
              YourEntity.class);
      return q.getSingleResult();
  }

I am using the following JPA related dependencies in the project:

<dependency>
  <groupId>org.eclipse.persistence</groupId>
  <artifactId>javax.persistence</artifactId>
  <version>2.0.0</version>
</dependency>

<dependency>
  <groupId>org.eclipse.persistence</groupId>
  <artifactId>eclipselink</artifactId>
  <version>2.0.2</version>
</dependency>

<dependency>
  <groupId>com.oracle</groupId>
  <artifactId>ojdbc6</artifactId>
  <version>11.1.0.7.0</version>
</dependency>

When I restart the glassfish, the exception does not occur any more. I have never seen the problem when undeploying/deploying an .ear with similar settings. Has anybody seen the error and knows how to overcome it? It is not a big problem, but annoying.

like image 944
Wintermute Avatar asked Dec 11 '12 15:12

Wintermute


1 Answers

Resources tied to the classloader are held statically until the EntityManagerFactories are closed. These are application managed so you must manually call close on the factories on shutdown or undeploy events when they are no longer needed - garbage collection might clean them up as well, but it is not occurring before the app is redeployed and accesses them again with a different classloader, resulting in the exception you see.

Hold onto the factory and close it when no longer needed, or use injection and allow the container to manage it's life cycle for you.

like image 117
Chris Avatar answered Sep 20 '22 07:09

Chris