enkor
enkor

Reputation: 7557

How to override WebSphere Community Edition (WCE) 2.1's default persistance provider- OpenJPA

In a Spring 3 MVC project running on WebSphere Community Edition 2.1, I'm trying to configure my entityManagerFactory. However it seems that I can't override the PersistanceProvider. It defaults to OpenJPA, and even excluded this as a hidden class:

<sys:hidden-classes>
  <sys:filter>org.apache.openjpa</sys:filter>
</sys:hidden-classes> 

However I get the following error in WebSphere when trying to deploy the application:

javax.persistence.PersistenceException: Invalid or inaccessible provider class: org.apache.openjpa.persistence.PersistenceProviderImpl

Even though I am providing a different provider(HibernatePersistence) in persistance.xml:

<persistence-unit name="com.intl.cigna">
  <description>
    Persistence unit for the JPA implementation
  </description>
  <provider>org.hibernate.ejb.HibernatePersistence</provider>
  <non-jta-data-source>java:comp/env/jdbc/myJndiDS</non-jta-data-source>
  <properties>
    <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServer2008Dialect"/>
    <property name="hibernate.show_sql" value="true" />            
  </properties>
</persistence-unit>

Upvotes: 2

Views: 1625

Answers (3)

enkor
enkor

Reputation: 7557

You can override the persistence provider via a ServletContextListener.

First implement a PersistenceProviderResolver:

public class HibernatePersistenceProviderResolver implements PersistenceProviderResolver {
    private static final Logger LOGGER = LoggerFactory.getLogger(HibernatePersistenceProviderResolver.class);

    private volatile PersistenceProvider persistenceProvider = new HibernatePersistence();

    public List<PersistenceProvider> getPersistenceProviders() {
    return Collections.singletonList(persistenceProvider);
    }

    public void clearCachedProviders() {
    persistenceProvider = new HibernatePersistence();
    }

    public static void register() {
    LOGGER.info("Registering HibernatePersistenceProviderResolver");
    PersistenceProviderResolverHolder.setPersistenceProviderResolver(new HibernatePersistenceProviderResolver());
    }
}

Then create an implemetation of a ServletContextListener and 'register' the ProviderResolver:

public class HibernateContextListener implements ServletContextListener{

    public void contextInitialized(ServletContextEvent sce) {
        HibernatePersistenceProviderResolver.register();    
    }

    public void contextDestroyed(ServletContextEvent sce) {
        // nothing to do here
    }
}

And add it as a listener in web.xml:

<listener>
    <listener-class>my.context.listener.HibernateContextListener</listener-class>
</listener>

Upvotes: 1

Glen Best
Glen Best

Reputation: 23105

To deploy the new JPA provider as a part of your application:

  1. Ensure persistence.xml <provider> element points to the new JPA provider's implementation of javax.persistence.spi.PersistenceProvider.

  2. Build the new JPA persistence code into the application - deploy all necessary jars into the your application EAR / WAR / CLASSPATH.

    Copy hibernate3.jar and the required 3rd party libraries available in lib/required Copy lib/jpa/hibernate-jpa-2.0-api-1.0.0.Final.jar to your classpath as well.

  3. Configure the app server class loader order for your application - load the new JPA classes first. If the class loader is not configured properly, the JPA provider that is included with the application server is used by your application instead of the third-party JPA provider.

  4. If you bundled the provider in an EAR file, in application modules that need JPA access, specify the third-party persistence provider binaries in the Manifest.mf class path.

    If you bundled the provider in a WAR file, include the necessary provider binaries in the WEB-INF/lib directory of the web application.

To deploy the new JPA provider within a shared library:

  1. Ensure persistence.xml <provider> element points to the new JPA provider's implementation of javax.persistence.spi.PersistenceProvider.

  2. Define the persistence provider in a shared library

  3. If the library is accessed by many applications, associate the shared library with the server class loader. Otherwise, associate the shared library with the application class loader.

  4. Configure the class loader order for your application - load the new JPA classes first. If the class loader is not configured properly, the JPA provider that is included with the application server is used by your application instead of the third-party JPA provider.

Websphere 8 JPA provider configuration
Hibernate 3.5 configuration
WAS CE - overriding class load order
WAS CE 2.0 - using frameworks, including Hibernate

Upvotes: 1

groo
groo

Reputation: 4448

you have to add the following properties to your persistence.xml file:

<property 
name="hibernate.transaction.factory_class"
value="org.hibernate.transaction.CMTTransactionFactory"
    />

    <property 
name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup"
    />

Also have all hibernate .jar libs added to your package lib folder(.war or .ear) and than change the class loading policy for the server to be Parent Last instead of the default Parent First, you can change that using the Domain Manager Console (Dmgr) at:

Servers > $SERVER_NAME > Server Specific Application Settings

Restart your server and this should do the trick.

regards.

Upvotes: 0

Related Questions