Spring + Hibernate + JPA: How to reload EntityManagerFactory at runtime

戏子无情 提交于 2019-12-07 09:13:49

问题


I have been searching for this the last few hours maybe some of you can help me.

I try to achieve a reload of my mapping info in EntityManagerFactory (or SessionFactory) at runtime in spring

The EntityManagerFactory is defined as follows:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
   <property name="persistenceXmlLocation" value="persistence.xml" />
   <property name="persistenceUnitName" value="JPAService" />
   <property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>
   <property name="dataSource" ref="dataSource" />
   <property name="jpaDialect">
     <bean class="org.springframework.orm.jpa.vendor.Hibernate.JpaDialect" />
   </property>
   <property name="jpaProperties">
     <props>
       <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
       <prop key="hibernate.hbm2ddl.auto">none</prop>
       <prop key="hibernate.show_sql">true</prop>
     </props>
   </property>      
</bean>

In my persistence.xml I just define the jar where the mapping files are

<?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="JPAService" transaction-type="RESOURCE_LOCAL">
    <jar-file>WEB-INF/lib/mapping.jar</jar-file>   
  </persistence-unit>
</persistence>


My hibernate mapping files will change very often and my app is using this files to generate part of the UI. Therefore I don't want to restart the server every time I change my hibernate mappings.

One thing I thought about is replacing EntityManagerFacotries/SessionFactory with a new one like so

Hibernate configuration on runtime
Dynamic Configure an EJB

but I do not know the side effects

Another way is to change (add/remove) the EntityManagerFactory/SessionFactory Mapping programatically at runtime:

JPA: adding entities to EntityManagerFactory programmatically
Programmatically loading Entity classes with JPA 2.0?

A very sophisticated scenario where no solution was found

Dynamic ORM entity class generation - NOT SOLVED

Another thead mentiones dynamic-JPA

How can I merge / extend persistence units from different JARs?
JPA 2.0: Adding entity classes to PersistenceUnit *from different jar* automatically

I already tried to update the whole application context from spring like so

@RequestMapping(value = { "/path" })
public ModelMap refresh(Model model, Locale locale) throws IOException,
  TemplateException, ExtJSException {

  ((ConfigurableApplicationContext)ApplicationContextProvider.getApplicationContext()).refresh();

  return getMessage("Context was refreshed!!");
}

But it seems as if this project isn't supported any more...


回答1:


I don't see any other solution besides reloading entire context.

All other practices could lead to memory leaks (on connections for example) or to all sorts of ClassNotFound and other things just image what will happen during a tx when you're trying to reconfigure the entitymanager alone

One solution I can think of is to "isolate" entire bean definition of the data-layer and replace the beans themselves thus avoiding a full app-context reload.

You can accomplish or by trying to create a new ApplicationContext, adding your data layer beans and replacing existing ones or by using a bunch of interfaces (for entitymanager, ds etc..) and replacing their implementation @ runtime (but will require a lot of work..)

you just need to make sure you're reloading the EntityManager + TX + DS (and perhaps other things I've forgot)

HTH



来源:https://stackoverflow.com/questions/8671776/spring-hibernate-jpa-how-to-reload-entitymanagerfactory-at-runtime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!