4

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...

Community
  • 1
  • 1
Jeremy S.
  • 6,423
  • 13
  • 48
  • 67
  • What is the class returned by ApplicationContextProvider.getApplicationContext()? – Saish Dec 30 '11 at 13:58
  • @Saish I use code like this [ApplicationContextProvider](http://blog.imaginea.com/making-a-spring-bean-applicationcontext-aware/) – Jeremy S. Dec 30 '11 at 18:08
  • That is well and good but not what I was trying to determine. If you call ApplicationContextProvider.getApplicationContext().getClass().getName(), what does that return? – Saish Dec 30 '11 at 18:31
  • The classname is ``org.springframework.web.context.support.XmlWebApplicationContext`` – Jeremy S. Jan 03 '12 at 09:45
  • The only other thing I can think of is that you could try instead to use ((AbstractRefreshableWebApplicationContext) WebApplicationContextUtils.getWebApplicationContext(ServletContext)).refresh(). – Saish Jan 03 '12 at 14:30
  • I will try out your solution hope it will work! – Jeremy S. Jan 21 '12 at 22:08
  • Did you manage to achieve this?? I also need to do something very similar – Frank Orellana Sep 06 '12 at 20:12
  • @Lando no luck so far. I talked to Josh Long at OSCON 2012 about this problem. And recommended to do it with refresh, but warned me that this is **bad practice** – Jeremy S. Sep 07 '12 at 07:00
  • Why do you need to refresh your hibernate mappings? Are you dynamically creating/removing columns or something? The whole thing sound like a bad idea. – alfredaday Feb 16 '14 at 05:19

1 Answers1

0

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

Yoni Moses
  • 173
  • 1
  • 13