问题描述
我最近继承了一个Spring / Hibernate应用程序,并将其升级到Spring 5.2.8
,SpringSecurity 5.3.4
,Hibernate 5.4.21
。
我们正在Websphere 8.5.5
(完全而非自由)上进行部署。
当我尝试运行该应用程序时,出现一个异常,我相信其中的相关部分是:
...嵌套的异常是org.springframework.beans.factory.BeanCreationException:创建在ServletContext资源[/WEB-INF/applicationContext-hibernate.xml]中定义的名称为“ auditSessionFactory”的bean时出错:调用init方法失败;嵌套异常是java.lang.NoSuchMethodError:javax / persistence / JoinColumn.foreignKey()Ljavax / persistence / ForeignKey; (由org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@2472a612从文件:/ C:/ Program Files(x86)/IBM/WebSphere/AppServer/plugins/javax.j2ee.persistence.jar加载)调用。 hibernate.cfg.AnnotationBinder(从文件:/ 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由 com.ibm.ws.classloader.CompoundClassLoader@71ed602b [war:nameof_war / nameof.war]
我注意到它正在使用JPA的Websphere版本,而不是战争中包含在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
此链接试图解释如何使用第三方持久性提供程序。
问题是,链接说要使用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>
解决方法
最终对我有帮助的是以下帖子:https://medium.com/@james.tran/how-to-deploy-spring-boot-2-x-apps-on-websphere-8-5-5-d0b2e257f606
具体地说,是以下步骤:
在管理控制台中,单击应用程序>应用程序类型> WebSphere企业应用程序> application_name>管理模块> webmodule_name。
从下拉列表中选择首先使用本地类加载器加载的类(最后是父类)。
我已经在控制台的其他位置完成了此操作,但是在这里还没有。
此外,我尝试了以下操作:
https://www.ibm.com/support/pages/apar/PM26361
- 打开管理控制台。
- 选择服务器->服务器类型-> WebSphere应用程序服务器。
- 选择要配置的服务器。
- 在“服务器基础结构”区域中,选择“ Java和流程管理->流程定义”。
- 在“服务器基础结构”区域中,选择“流程定义”。
- 在“其他属性”区域中,选择“ Java虚拟机”。
- 在“其他属性”区域中,选择“自定义属性”。
- 选择“新建”框。
- 在“名称”输入字段中,输入:com.ibm.websphere.persistence.ApplicationsExcludedFromJpaProcessing
- 在“值”输入字段中,输入要从JPA处理中排除的应用程序的名称。如果有多个应用程序 用“:”字符分隔每个字符。如果您要指定全部 应用程序只需键入“ *”字符即可。
- 选择确定。
- 重新启动服务器。
我不知道哪些步骤有帮助-如果有机会,我会尝试缩小范围并报告。