春天 +休眠+ JPA:如何在运行时重新加载 EntityManagerFactory
过去几个小时我一直在寻找这个,也许你们中的一些人可以帮助我。
我尝试在 Spring 运行时在 EntityManagerFactory (或 SessionFactory)中实现 重新加载我的映射信息
EntityManagerFactory 定义如下:
<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>
在我的 persistence.xml 中,我只定义映射文件所在的 jar
<?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>
< br> 我的休眠映射文件会经常更改,我的应用程序正在使用这些文件来生成部分 UI。因此,我不想每次更改休眠映射时都重新启动服务器。
我想到的一件事是用新的替换 EntityManagerFacotries/SessionFactory,如下所示
但我不知道副作用
另一种方法是更改(添加/在运行时以编程方式删除)EntityManagerFactory/SessionFactory 映射:
JPA:以编程方式将实体添加到 EntityManagerFactory
使用 JPA 2.0 以编程方式加载实体类?
A非常复杂的场景,找不到解决方案
另一个主题提到动态 JPA
如何合并/扩展来自不同 JAR 的持久性单元?
JPA 2.0:向 PersistenceUnit 添加实体类*自动从不同的jar*
我已经尝试像这样从spring更新整个应用程序上下文
@RequestMapping(value = { "/path" })
public ModelMap refresh(Model model, Locale locale) throws IOException,
TemplateException, ExtJSException {
((ConfigurableApplicationContext)ApplicationContextProvider.getApplicationContext()).refresh();
return getMessage("Context was refreshed!!");
}
但似乎不再支持这个项目......
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...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
除了重新加载整个上下文之外,我没有看到任何其他解决方案。
所有其他做法都可能导致内存泄漏(例如在连接上)或导致各种 ClassNotFound 和其他问题
只是想象一下,当您尝试单独重新配置实体管理器时,在 tx 期间会发生什么
我能想到的一个解决方案是“隔离”数据层的整个 bean 定义并替换 bean 本身,从而避免完整的应用程序上下文重新加载。
您可以通过尝试创建新的 ApplicationContext、添加数据层 bean 并替换现有的 bean 或使用一堆接口(用于实体管理器、ds 等)来完成或完成
并在运行时替换它们的实现(但需要大量工作..),
您只需要确保重新加载 EntityManager + TX + DS(也许还有我忘记的其他事情)
HTH
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