如何修复获取当前休眠会话时的空指针异常



在基于 Spring 5/Hibernate5 构建的 WebSphere 9 应用程序中,我在检索当前 Hibernate 会话时收到此错误org.hibernate.SessionFactory.getCurrentSession()

[9/26/19 10:41:22:405 CEST] 0001f184 DefaultMessag W org.springframework.jms.listener.AbstractMessageListenerContainer invokeErrorHandler Execution of JMS message listener failed, and no ErrorHandler has been set.
java.lang.IllegalStateException: An exception occured during the cumulation before the processingId could be created: java.lang.NullPointerException
at com.tsystems.cc4.service.cumulation.CumulationHandlerImpl.cumulate(CumulationHandlerImpl.java:138)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:508)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at com.tsystems.cc4.service.cumulation.NonClosingOpenSessionInterceptor.invoke(NonClosingOpenSessionInterceptor.java:40)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy184.cumulate(Unknown Source)
at com.tsystems.cc4.service.cumulation.ScheduleCommandHandler.invoke(ScheduleCommandHandler.java:62)
at com.tsystems.cc4.service.invocation.listener.InvocationWrapperListener.onMessage(InvocationWrapperListener.java:128)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:736)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:696)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:674)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:318)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:245)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1189)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1081)
at javax.enterprise.concurrent.ManagedExecutors$RunnableAdapter.run(ManagedExecutors.java:211)
at com.ibm.ws.asynchbeans.SubmittedTask.run(SubmittedTask.java:711)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1909)
Caused by: java.lang.NullPointerException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:508)
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282)
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:266)
at org.springframework.orm.hibernate5.SessionFactoryUtils.getFlushMode(SessionFactoryUtils.java:125)
at org.springframework.orm.hibernate5.SpringSessionContext.currentSession(SpringSessionContext.java:100)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:456)
at com.tsystems.cc4.control.dao.impl.AbstractHibernateDAO.getSession(AbstractHibernateDAO.java:51)
at com.tsystems.cc4.control.dao.impl.GenericCrudDAOImpl.readInReadOnlyMode(GenericCrudDAOImpl.java:107)
at com.tsystems.cc4.service.cumulation.CumulationHandlerImpl.cumulate(CumulationHandlerImpl.java:120)
... 23 more
[9/26/19 10:41:22:415 CEST] 0001f184 TransactionSy E org.springframework.transaction.support.TransactionSynchronizationUtils triggerBeforeCompletion TransactionSynchronization.beforeCompletion threw exception
java.lang.NullPointerException
at org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCompletion(SpringSessionSynchronization.java:110)
at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCompletion(TransactionSynchronizationUtils.java:107)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCompletion(AbstractPlatformTransactionManager.java:935)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:826)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:702)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:251)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1189)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1081)
at javax.enterprise.concurrent.ManagedExecutors$RunnableAdapter.run(ManagedExecutors.java:211)
at com.ibm.ws.asynchbeans.SubmittedTask.run(SubmittedTask.java:711)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1909)

应用程序代码在Spring 4.3.14.RELEASE + Hibernate 4.2.21.Final上成功运行。

自从我们升级到Spring 5.1.1.RELEASE + Hibernate 5.2.9.Final以来,就会出现问题。

之前的 Spring 配置(Spring 4.3.14.RELEASE + Hibernate 4.2.21.Final(:

<bean id="cumulationConfigDAO" class="com.tsystems.cc4.control.dao.impl.GenericCrudDAOImpl">
<constructor-arg value="com.tsystems.cc4.control.model.cumulation.CumulationConfig" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="controlDataSource" />
<property name="packagesToScan" value="com.tsystems.cc4.control.model" />
<property name="hibernateProperties">
<value>
hibernate.default_schema=CC4
hibernate.dialect=org.hibernate.dialect.${jdbc.dialect}Dialect
org.jboss.logging.provider=slf4j
${hib_tx_platform}
${hib_tx_factory}
</value>
</property>
</bean>

性能:

# Settings for DB2
jdbc.dialect=DB2
# Hibernate JTA Transaction Platform configuration
hib_tx_platform=hibernate.transaction.jta.platform=org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform
hib_tx_factory=hibernate.transaction.factory_class=org.hibernate.transaction.CMTTransactionFactory

Spring 配置之后(Spring 5.1.1.RELEASE + Hibernate 5.2.9.Final(:

<bean id="cumulationConfigDAO" class="com.tsystems.cc4.control.dao.impl.GenericCrudDAOImpl">
<constructor-arg name="entityClass" value="com.tsystems.cc4.control.model.cumulation.CumulationConfig" />
<constructor-arg name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="controlDataSource" />
<property name="packagesToScan" value="com.tsystems.cc4.control.model" />
<property name="hibernateProperties">
<value>
hibernate.default_schema=CC4
hibernate.dialect=org.hibernate.dialect.${jdbc.dialect}Dialect
org.jboss.logging.provider=slf4j
${hib_tx_platform}
${hib_tx_factory}
hibernate.id.new_generator_mappings=false
hibernate.allow_update_outside_transaction=true
</value>
</property>
</bean>

性能:

# Settings for DB2
jdbc.dialect=DB2
# Hibernate JTA Transaction Platform configuration
hib_tx_platform=hibernate.transaction.jta.platform=org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform
hib_tx_factory=hibernate.transaction.factory_class=org.hibernate.transaction.CMTTransactionFactory

已解决。问题的原因是我们以前构建的一些专门的东西,用于解决从 Hibernate 3 迁移到 Hibernate 4 后的问题。Spring 上下文包含这样的非标准内容:

<!-- The Hibernate interceptor, which takes care of opening and closing 
hibernate session around method calls. -->
<bean id="hibernateInterceptor"
class="com.tsystems.cc4.service.cumulation.NonClosingOpenSessionInterceptor">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<!-- A proxy with the hibernate interceptor wired in so it can access 
the persistent context -->
<bean id="cumulationHandler" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<bean class="com.tsystems.cc4.service.cumulation.CumulationHandlerImpl" />
</property>
<property name="proxyInterfaces">
<value>com.tsystems.cc4.service.cumulation.CumulationHandler</value>
</property>
<property name="interceptorNames">
<value>hibernateInterceptor</value>
</property> 
</bean>

去除这些豆子解决了这个问题。

这是来自NonClosingOpenSessionInterceptor类评论:">org.springframework.orm.hibernate4.support.OpenSessionInterceptor的专用版本,如有必要,打开Hibernate会话并将其注册到Spring的TransactionSynchronizationManager,而无需在方法调用后关闭它。如果在事务完成期间通过事务管理器关闭休眠会话,则这是必需的。 创建此类是为了解决将 org.springframework.orm.hibernate4.support.OpenSessionInterceptor 与 Spring 的 PlatformTransactionManager 结合使用时出现的"org.hibernate.SessionException: Session is closed!"问题。

@Transactional使用 服务方法还是道方法?

最新更新