You are here

Seam, JPA & Resin

on Nov 3, 2009

These days I am transportting some seam-jpa based web applications from jboss to resin. But found there is a bug for seam to create EntityManagerFactory in resin:

[19:34:46.510]org.jboss.seam.InstantiationException: Could not instantiate Seam
component: application_form_Database
[19:34:46.510]  at org.jboss.seam.Component.newInstance(Component.java:2144)
[19:34:46.510]  at org.jboss.seam.contexts.Contexts.startup(Contexts.java:304)

...

[19:34:46.510]  at com.caucho.server.resin.Resin.main(Resin.java:1365)
[19:34:46.510]Caused by: java.lang.NullPointerException
[19:34:46.510]  at com.caucho.amber.manager.AmberPersistenceProvider.createEntit
yManagerFactory(AmberPersistenceProvider.java:65)
[19:34:46.510]  at javax.persistence.Persistence.createEntityManagerFactory(Pers
istence.java:69)
[19:34:46.510]  at org.jboss.seam.persistence.EntityManagerFactory.createEntityM
anagerFactory(EntityManagerFactory.java:81)

After consulting the source code of resin, I found the AmberPersistenceProvider maybe didn't get proper parameter from seam. Anyway, fix this on seam is much easier on resin, so I write below class:

--------------------------------------------------------------------------------

package ...seam.persistence;

import ...

@Scope(ScopeType.APPLICATION)
@BypassInterceptors
@Startup
public class EntityManagerfactory extends org.jboss.seam.persistence.EntityManagerFactory
{
   @Override
   protected javax.persistence.EntityManagerFactory createEntityManagerFactory()
   {
      PersistenceProvider []providers = getProviderList();

      for (int i = 0; i < providers.length; i++) {
         // Only permit HibernatePersistence provider
         if ( !(providers[i] instanceof org.hibernate.ejb.HibernatePersistence) )
            continue;

         EntityManagerFactory factory;

        factory = providers[i].createEntityManagerFactory(this.getPersistenceUnitName(), null);

        if (factory != null)
          return factory;
      }

      //HibernatePersistence hp = HibernatePersistence.createEntityManagerFactory
      //createEntityManagerFactory(this.getPersistenceUnitName(), null);
      return null;
   }
}

--------------------------------------------------------------------------------

This method was copied from javax.persistence.createEntityManagerFactory, please notice 3 lines added to only permit HibernatePersistence provider, resin's AmberPersistenceProvider was ignored.

After add this class, in components.xml:

--------------------------------------------------------------------------------

    <persistence:entity-manager-factory
            name="application_form_Database"
            class="...seam.persistence.EntityManagerfactory" />

--------------------------------------------------------------------------------

With these patch JPA can work properly on resin.