Seam, JPA & Resin
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.