2

在 WebSphere Community Edition 2.1 上运行的 Spring 3 MVC 项目中,我正在尝试配置我的 entityManagerFactory。但是,我似乎无法覆盖 PersistanceProvider。它默认为 OpenJPA,甚至将其排除为隐藏类:

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

但是,在尝试部署应用程序时,我在 WebSphere 中收到以下错误:

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

即使我在persistance.xml 中提供了不同的提供者(HibernatePersistence):

<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>
4

3 回答 3

1

要将新的 JPA 提供程序部署为应用程序的一部分:

  1. 确保persistence.xml <provider>元素指向新 JPA 提供者的javax.persistence.spi.PersistenceProvider.

  2. 将新的 JPA 持久性代码构建到应用程序中 - 将所有必要的 jar 部署到您的应用程序 EAR/WAR/CLASSPATH 中。

    复制 hibernate3.jar 和 lib/required 中可用的所需 3rd 方库 将 lib/jpa/hibernate-jpa-2.0-api-1.0.0.Final.jar 也复制到您的类路径中。

  3. 为您的应用程序配置应用服务器类加载器顺序 - 首先加载新的 JPA 类。 如果未正确配置类加载器,应用程序服务器中包含的 JPA 提供程序将由您的应用程序使用,而不是第三方 JPA 提供程序。

  4. 如果您将提供程序捆绑在 EAR 文件中,那么在需要 JPA 访问的应用程序模块中,在 Manifest.mf 类路径中指定第三方持久性提供程序二进制文件。

    如果您将提供程序捆绑在 WAR 文件中,请在 Web 应用程序的 WEB-INF/lib 目录中包含必要的提供程序二进制文件。

要在共享库中部署新的 JPA 提供程序:

  1. 确保persistence.xml <provider>元素指向新 JPA 提供者的javax.persistence.spi.PersistenceProvider.

  2. 在共享库中定义持久性提供程序

  3. 如果该库被许多应用程序访问,请将共享库与服务器类加载器相关联。否则,将共享库与应用程序类加载器相关联。

  4. 为您的应用程序配置类加载器顺序 - 首先加载新的 JPA 类。 如果未正确配置类加载器,应用程序服务器中包含的 JPA 提供程序将由您的应用程序使用,而不是第三方 JPA 提供程序。

Websphere 8 JPA 提供者配置
Hibernate 3.5 配置
WAS CE - 覆盖类加载顺序
WAS CE 2.0 - 使用框架,包括 Hibernate

于 2012-11-05T08:38:25.287 回答
1

您可以通过 ServletContextListener 覆盖持久性提供程序。

首先实现一个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());
    }
}

然后创建一个实现ServletContextListener并“注册”ProviderResolver:

public class HibernateContextListener implements ServletContextListener{

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

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

并将其添加为 web.xml 中的侦听器:

<listener>
    <listener-class>my.context.listener.HibernateContextListener</listener-class>
</listener>
于 2012-11-19T10:01:43.173 回答
0

您必须将以下属性添加到您的 persistence.xml 文件中:

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

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

还将所有休眠 .jar 库添加到您的包库文件夹(.war 或 .ear)中,然后将服务器的类加载策略更改为 Parent Last 而不是默认的 Parent First,您可以使用域管理器控制台进行更改(Dmgr)在:

服务器 > $SERVER_NAME > 服务器特定应用程序设置

重新启动您的服务器,这应该可以解决问题。

问候。

于 2012-10-31T16:40:13.217 回答