Spring/Hibernate 在关闭 EntityManagerFactory 之前添加关闭钩子 运行
Spring/Hibernate adding a shutdown hook running prior to closing the EntityManagerFactory
当我关闭我的服务器时,我有一些作业正在填充下载和填充数据,我希望这些作业可以优雅地完成。
我试图添加一个 Runtime.getRuntime().addShutDownHook() 但这似乎 运行 在 Entitymanager 已经关闭之后,因为异常在 运行 之前开始涌入.
然后我尝试添加它来实现一个 ServletContextListener 和
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent)
which 运行 在关闭挂钩之前但仍在 entitymanager 已经关闭之后。
有没有办法在 entitymanager 关闭之前 运行 一些逻辑?
我正在使用
注入 entitymanager
@PersistenceContext(unitName = PERSISTENCE_UNIT)
private EntityManager entityManager;
EntitymanagerFactory 是使用
创建的
@Configuration
@Bean(name= PERSISTENCE_UNIT)
.... createEntityManagerFactory()
我如何正确地监听 entitymanager 关闭的时间,以便让挂起的工作先完成?
我在 Java EE 上使用 Spring、Hibernate、JPA 和 Web 模块。
产生的异常是这样的:
java.lang.IllegalStateException: EntityManagerFactory is closed
org.hibernate.jpa.internal.EntityManagerFactoryImpl.validateNotClosed(EntityManagerFactoryImpl.java:388)
org.hibernate.jpa.internal.EntityManagerFactoryImpl.internalCreateEntityManager(EntityManagerFactoryImpl.java:342)
org.hibernate.jpa.internal.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:313)
sun.reflect.GeneratedMethodAccessor62.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:497)
org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.invokeProxyMethod(AbstractEntityManagerFactoryBean.java:388)
org.springframework.orm.jpa.AbstractEntityManagerFactoryBean$ManagedEntityManagerFactoryInvocationHandler.invoke(AbstractEntityManagerFactoryBean.java:541)
com.sun.proxy.$Proxy51.createEntityManager(Unknown Source)
org.springframework.orm.jpa.EntityManagerFactoryUtils.doGetTransactionalEntityManager(EntityManagerFactoryUtils.java:285)
org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:252)
com.sun.proxy.$Proxy53.getDelegate(Unknown Source)
当 Spring 应用程序上下文被销毁时,EntityManagerFactory
被关闭。
根据您记录的异常,主 运行 线程检测到应用程序销毁事件并且 Spring shutdownHook 将销毁事件传播到所有已注册的 bean,包括 EntityManagerFactory
。
您可能有一个批处理作业,其中有一些工作线程,它们不监听应用程序销毁事件,因此它们继续执行,因此尝试使用关闭的 [=10] 创建一个 EntityManager
=].
因为application context被破坏了,关闭的不仅仅是EntityManagerFactory
,还有TransactionManager
和DataSource
。这就是为什么您对此无能为力,除了放弃当前的 运行 批处理作业并简单地取消确认
未完成的项目。
解决方案是使用持久化消息队列来记录任何待处理的工作。如果服务器已关闭,则不应确认当前正在处理的消息,以便在您下次启动服务器时重新处理它们。
当我关闭我的服务器时,我有一些作业正在填充下载和填充数据,我希望这些作业可以优雅地完成。
我试图添加一个 Runtime.getRuntime().addShutDownHook() 但这似乎 运行 在 Entitymanager 已经关闭之后,因为异常在 运行 之前开始涌入.
然后我尝试添加它来实现一个 ServletContextListener 和
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent)
which 运行 在关闭挂钩之前但仍在 entitymanager 已经关闭之后。
有没有办法在 entitymanager 关闭之前 运行 一些逻辑?
我正在使用
注入 entitymanager@PersistenceContext(unitName = PERSISTENCE_UNIT)
private EntityManager entityManager;
EntitymanagerFactory 是使用
创建的@Configuration
@Bean(name= PERSISTENCE_UNIT)
.... createEntityManagerFactory()
我如何正确地监听 entitymanager 关闭的时间,以便让挂起的工作先完成?
我在 Java EE 上使用 Spring、Hibernate、JPA 和 Web 模块。
产生的异常是这样的:
java.lang.IllegalStateException: EntityManagerFactory is closed
org.hibernate.jpa.internal.EntityManagerFactoryImpl.validateNotClosed(EntityManagerFactoryImpl.java:388)
org.hibernate.jpa.internal.EntityManagerFactoryImpl.internalCreateEntityManager(EntityManagerFactoryImpl.java:342)
org.hibernate.jpa.internal.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:313)
sun.reflect.GeneratedMethodAccessor62.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:497)
org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.invokeProxyMethod(AbstractEntityManagerFactoryBean.java:388)
org.springframework.orm.jpa.AbstractEntityManagerFactoryBean$ManagedEntityManagerFactoryInvocationHandler.invoke(AbstractEntityManagerFactoryBean.java:541)
com.sun.proxy.$Proxy51.createEntityManager(Unknown Source)
org.springframework.orm.jpa.EntityManagerFactoryUtils.doGetTransactionalEntityManager(EntityManagerFactoryUtils.java:285)
org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:252)
com.sun.proxy.$Proxy53.getDelegate(Unknown Source)
当 Spring 应用程序上下文被销毁时,EntityManagerFactory
被关闭。
根据您记录的异常,主 运行 线程检测到应用程序销毁事件并且 Spring shutdownHook 将销毁事件传播到所有已注册的 bean,包括 EntityManagerFactory
。
您可能有一个批处理作业,其中有一些工作线程,它们不监听应用程序销毁事件,因此它们继续执行,因此尝试使用关闭的 [=10] 创建一个 EntityManager
=].
因为application context被破坏了,关闭的不仅仅是EntityManagerFactory
,还有TransactionManager
和DataSource
。这就是为什么您对此无能为力,除了放弃当前的 运行 批处理作业并简单地取消确认
未完成的项目。
解决方案是使用持久化消息队列来记录任何待处理的工作。如果服务器已关闭,则不应确认当前正在处理的消息,以便在您下次启动服务器时重新处理它们。