spring/hibernate 在 Websphere 上使用 jpa2.2

Using jpa2.2 on Websphere with spring/hibernate

我最近继承了一个 Spring/Hibernate 应用程序,并将其升级到 Spring 5.2.8SpringSecurity 5.3.4Hibernate 5.4.21

我们正在 Websphere 8.5.5 上部署(完整,而非自由)。

当我尝试 运行 应用程序时,出现异常,我认为相关部分是:

...nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'auditSessionFactory' defined in ServletContext resource [/WEB-INF/applicationContext-hibernate.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: javax/persistence/JoinColumn.foreignKey()Ljavax/persistence/ForeignKey; (loaded from file:/C:/Program Files (x86)/IBM/WebSphere/AppServer/plugins/javax.j2ee.persistence.jar by org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@2472a612) called from class org.hibernate.cfg.AnnotationBinder (loaded from file:/C:/Program%20Files%20(x86)/IBM/WebSphere/AppServer/profiles/AppSrv01/installedApps/Node01Cell/nameof_war.ear/nameof.war/WEB-INF/lib/hibernate-core-5.4.21.Final.jar by com.ibm.ws.classloader.CompoundClassLoader@71ed602b[war:nameof_war/nameof.war]

我注意到它使用的是 JPA 的 Websphere 版本,而不是我包含在 war 中的 jar 版本。 Websphere 自带 javax.j2ee.persistence.jar - JPA 版本 2.0,它解释了错误。

对另一个 SO 问题的回答让我来到这里:https://www.ibm.com/support/knowledgecenter/en/SSAW57_8.5.5/com.ibm.websphere.nd.multiplatform.doc/ae/tejb_jpa3rdparty.html

本文link试图解释如何使用第三方持久性提供程序。

问题是,link 说要使用 persistence.xml;但是我继承的应用程序没有那个 xml 文件。它只有 applicationContext-hibernate.xml 和 orm.xml.

我试过创建 persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
  <persistence xmlns="http://java.sun.com/xml/ns/persistence"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
 http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
   <persistence-unit name="nameof">
      <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
      <jar-file>nameof.jar</jar-file>
   </persistence-unit>
  </persistence>

它出现在 WAR 文件的正确位置;但我不知道这是否正确 - 也不知道我是否还必须更新任何其他文件?我是否需要在其他地方引用该持久性单元?

我还更新了 WebSphere 中的类加载器,使其成为最后一个父类;但我仍然收到如上所示的错误。

我缺少哪些步骤?我需要在 applicationContext-hibernate.xml(或其他地方)中进行哪些更改才能使其正常工作?

我的 applicationContext-hibernate.xml 看起来像:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
                           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

  <bean id="auditSessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="annotatedClasses">
      <list>
        <value>com.name.class1</value>
        <value>com.name.class2</value>
        <value>etc</value>
      </list>
    </property> 
      <property name="mappingResources">
      <list>
        <value>com/name/model/orm.xml</value>
      </list>
    </property>
    <property name="hibernateProperties">
      <props>
        <prop key="hibernate.dialect">org.hibernate.dialect.Oracle12cDialect</prop>
        <prop key="hibernate.jdbc.fetch_size">100</prop>
      </props>
    </property>
  </bean>

  <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="annotatedClasses">
      <list>
        <value>com.name.class3</value>
        <value>com.name.class4</value>
        <value>etc</value>
      </list>
    </property> 
    <property name="mappingResources">
      <list>
        <value>com/name/model/orm.xml</value>
      </list>
    </property>
    <property name="hibernateProperties">
      <props>
        <prop key="hibernate.dialect">org.hibernate.dialect.Oracle12cDialect</prop>
        <prop key="hibernate.jdbc.fetch_size">100</prop>
        <prop key="hibernate.format_sql">true</prop>
        <prop key="hibernate.order_inserts">true</prop>  
        <prop key="hibernate.order_updates">true</prop> 
        <prop key="hibernate.jdbc.batch_size">100</prop>
      </props>
    </property>
    <property name="entityInterceptor">
      <bean class="com.name.interceptor.HibernateInterceptor">
        <property name="auditInterceptor">
            <bean class="com.name.interceptor.AuditInterceptor" />
        </property>
        <property name="comparativeAuditInterceptor">
            <bean class="com.name.interceptor.ComparativeAuditInterceptor">
                <property name="cadDao">
                    <bean class="com.name.dao.ComparativeAuditDetailsDaoImpl">
                        <property name="sessionFactory" ref="auditSessionFactory" />
                    </bean>
                </property>
                <property name="undoDao">
                    <bean class="com.name.dao.UndoDaoImpl">
                        <property name="sessionFactory" ref="auditSessionFactory" />
                    </bean>
                </property>
            </bean>
        </property>
      </bean>
    </property>
  </bean>

  <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
  </bean>


  <tx:annotation-driven transaction-manager="transactionManager"/>

  <bean id="openSessionInViewInterceptor"
        class="org.springframework.orm.hibernate5.support.OpenSessionInViewInterceptor">
    <property name="sessionFactory" ref="sessionFactory"/>
  </bean>

  <bean id="transactionInterceptor" class="com.name.TransactionalWebRequestInterceptor">
    <property name="transactionManager" ref="transactionManager"/>
    <property name="transactionAttribute" value="PROPAGATION_REQUIRES_NEW"/>
  </bean>

</beans>

最终帮助我的是以下post:https://medium.com/@james.tran/how-to-deploy-spring-boot-2-x-apps-on-websphere-8-5-5-d0b2e257f606

具体如下步骤:

In the administrative console, click Applications > Application Types > WebSphere enterprise applications > application_name > Manage modules > webmodule_name.

Select Classes loaded with local class loader first (parent last) from the drop down list.

我已经在控制台的其他地方这样做了,但这里没有。

此外,我尝试了以下方法:

https://www.ibm.com/support/pages/apar/PM26361

  1. Open the administrative console.
  2. Select Servers -> Server Types -> WebSphere application servers.
  3. Select the server you want to configure.
  4. In the Server Infrastructure area, select Java and Process Management -> Process definition.
  5. In the Server Infrastructure area, select Process Definition.
  6. In the Additional Properties area, select Java Virtual Machine.
  7. In the Additional Properties area, select Custom Properties.
  8. Select the New box.
  9. In the Name entry field, type: com.ibm.websphere.persistence.ApplicationsExcludedFromJpaProcess ing
  10. In the Value entry field, type the names of the applications to be excluded from JPA processing. If there are multiple appli[c]ations separate each with the ":" character. If you wish to specify all applications simply type the "*" character.
  11. Select OK.
  12. Restart the server.

我不知道哪些步骤有帮助 - 我会尝试缩小范围并在有机会时报告。