春天 +休眠+ JPA:如何在运行时重新加载 EntityManagerFactory

发布于 2024-12-23 12:18:38 字数 3398 浏览 1 评论 0原文

过去几个小时我一直在寻找这个,也许你们中的一些人可以帮助我。

我尝试在 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,如下所示

运行时的 Hibernate 配置
动态配置 EJB

但我不知道副作用

另一种方法是更改​​(添加/在运行时以编程方式删除)EntityManagerFactory/SessionFactory 映射:

JPA:以编程方式将实体添加到 EntityManagerFactory
使用 JPA 2.0 以编程方式加载实体类?

A非常复杂的场景,找不到解决方案

动态 ORM 实体类生成 - 未解决

另一个主题提到动态 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

烟─花易冷 2024-12-30 12:18:38

除了重新加载整个上下文之外,我没有看到任何其他解决方案。

所有其他做法都可能导致内存泄漏(例如在连接上)或导致各种 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文