2015-02-07 4 views
2

Когда я закрываю свой сервер, у меня есть задания, которые заполняют загрузку и заполнение данных, которые я хотел бы разрешить закончить изящно.Spring/Hibernate добавляет крюк завершения работы до закрытия EntityManagerFactory

Я попытался добавить Runtime.getRuntime(). AddShutDownHook(), но это кажется запущенным после того, как Entitymanager уже закрыт, поскольку исключение начинает заливаться до того, как он будет запущен.

Тогда я пытался добавить его реализовать и контекста сервлета

@Override 
public void contextDestroyed(ServletContextEvent servletContextEvent) 

который бежал до выключения крюка, но все же после того, как EntityManager уже закрыт.

Есть ли способ запустить некоторую логику до выключения сущ.

Я инъекции EntityManager, используя

@PersistenceContext(unitName = PERSISTENCE_UNIT) 
private EntityManager entityManager; 

EntityManagerFactory создается с помощью

@Configuration 

@Bean(name= PERSISTENCE_UNIT) 
.... createEntityManagerFactory() 

Как правильно слушать, когда EntityManager получает закрыты, так что я могу позволить в ожидании работы, чтобы завершить первый?

Я использую Spring, Hibernate, JPA на Java EE с веб-модулем.

Полученное исключение заключается в следующем:

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) 

ответ

0

Это EntityManagerFactory, которые получают сомкнулись, когда контекст Spring приложения разрушается.

В соответствии с вашим зарегистрированным исключением основной поток работает с обнаружением события уничтожения приложения, а Spring shutdownHook передает событие уничтожения всем зарегистрированным компонентам, включенным EntityManagerFactory.

Возможно, у вас есть пакетное задание, в котором есть некоторые рабочие потоки, которые не прослушивают событие уничтожения приложения, и поэтому они продолжают выполняться, поэтому пытаются создать EntityManager с использованием закрытого EntityManagerFactory.

Поскольку контекст приложения разрушен, это не только закрытое окно EntityManagerFactory, но и TransactionManager и DataSource. Вот почему вы мало что можете с этим поделать, кроме отбрасывания текущих текущих партийных заданий и просто неузнаваемости незавершенных предметов .

Решение заключается в использовании постоянной очереди сообщений для записи любой ожидающей работы. Если сервер закрыт, текущие обрабатывающие сообщения не должны быть подтверждены, и поэтому они получат возможность быть переработаны при следующем запуске вашего сервера.

Смежные вопросы