I recently inherited a Spring/Hibernate app, and upgraded it to Spring 5.2.8
, SpringSecurity 5.3.4
, Hibernate 5.4.21
.
We are deploying on Websphere 8.5.5
(full, not liberty).
When I try to run the application, I get an exception, of which I believe the relevant part is:
...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]
I noticed that it is using the Websphere version of JPA, rather than the one I included in the jar within the war. Websphere comes with javax.j2ee.persistence.jar
- JPA version 2.0
, which explains the error.
An answer to another SO question led me here: https://www.ibm.com/support/knowledgecenter/en/SSAW57_8.5.5/com.ibm.websphere.nd.multiplatform.doc/ae/tejb_jpa3rdparty.html
This link tried to explain how to use third-party persistence providers.
The problem is, the link says to use persistence.xml
; but the application I've inherited doesn't have that xml file. It only has applicationContext-hibernate.xml
and orm.xml.
I have tried creating a 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>
Which appears in the right place in the WAR file; but I don't know if that's correct or not - nor if I have to update any other files as well? Do I need to reference that persistence-unit somewhere else?
I've also updated the classloader in WebSphere to be parent last; but I still get the error as shown above.
What steps am I missing? What do I need do change in applicationContext-hibernate.xml
(or elsewhere) to get this working?
My applicationContext-hibernate.xml
looks like:
<?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>
spring context config
andweblogic-application.xml
in this case? Also I don't think I'm using JNDI? – simonalexander2005