Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programmatic SchemaExport / SchemaUpdate with Hibernate 5 and Spring 4

Tags:

With Spring 4 and Hibernate 4, I was able to use Reflection to get the Hibernate Configuration object from the current environment, using this code:

@Autowired LocalContainerEntityManagerFactoryBean lcemfb;  EntityManagerFactoryImpl emf = (EntityManagerFactoryImpl) lcemfb.getNativeEntityManagerFactory(); SessionFactoryImpl sf = emf.getSessionFactory(); SessionFactoryServiceRegistryImpl serviceRegistry = (SessionFactoryServiceRegistryImpl) sf.getServiceRegistry(); Configuration cfg = null;  try {     Field field = SessionFactoryServiceRegistryImpl.class.getDeclaredField("configuration");     field.setAccessible(true);     cfg = (Configuration) field.get(serviceRegistry); } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {     e.printStackTrace(); }  SchemaUpdate update = new SchemaUpdate(serviceRegistry, cfg); 

With Hibernate 5, I must use some MetadataImplementor, which doesn't seems to be available from any of those objects. I also tried to use MetadataSources with the serviceRegistry. But it did say that it's the wrong kind of ServiceRegistry.

Is there any other way to get this working?

like image 546
Benjamin M Avatar asked Jan 05 '16 12:01

Benjamin M


1 Answers

Basic idea for this problem is:

implementation of org.hibernate.integrator.spi.Integrator which stores required data to some holder. Register implementation as a service and use it where you need.

Work example you can find here https://github.com/valery-barysok/spring4-hibernate5-stackoverflow-34612019


create org.hibernate.integrator.api.integrator.Integrator class

import hello.HibernateInfoHolder; import org.hibernate.boot.Metadata; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.service.spi.SessionFactoryServiceRegistry;  public class Integrator implements org.hibernate.integrator.spi.Integrator {      @Override     public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {         HibernateInfoHolder.setMetadata(metadata);         HibernateInfoHolder.setSessionFactory(sessionFactory);         HibernateInfoHolder.setServiceRegistry(serviceRegistry);     }      @Override     public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {     } } 

create META-INF/services/org.hibernate.integrator.spi.Integrator file

org.hibernate.integrator.api.integrator.Integrator 

import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.hibernate.tool.hbm2ddl.SchemaUpdate; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;  @SpringBootApplication public class Application implements CommandLineRunner {      public static void main(String[] args) {         SpringApplication.run(Application.class, args);     }      @Override     public void run(String... args) throws Exception {         new SchemaExport((MetadataImplementor) HibernateInfoHolder.getMetadata()).create(true, true);         new SchemaUpdate(HibernateInfoHolder.getServiceRegistry(), (MetadataImplementor) HibernateInfoHolder.getMetadata()).execute(true, true);     } } 
like image 65
valery.barysok Avatar answered Sep 23 '22 05:09

valery.barysok