All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.webpieces.plugin.hibernate.HibernateModule Maven / Gradle / Ivy

There is a newer version: 2.1.109
Show newest version
package org.webpieces.plugin.hibernate;

import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import com.google.inject.Provides;
import com.google.inject.multibindings.Multibinder;

import io.micrometer.core.instrument.MeterRegistry;

import org.hibernate.cfg.AvailableSettings;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.webpieces.router.api.extensions.EntityLookup;

import javax.inject.Singleton;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.spi.PersistenceUnitInfo;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

public class HibernateModule extends AbstractModule {

	private static final Logger log = LoggerFactory.getLogger(HibernateModule.class);
	private Supplier persistenceUnit;
	private ClassLoader entityClassLoader;
	private Supplier loadByClassFile;
	private boolean transactionOnByDefault;

	public HibernateModule(Supplier persistenceUnit2, Supplier loadByClassFile, boolean transactionOnByDefault) {
		this.loadByClassFile = loadByClassFile;
		this.transactionOnByDefault = transactionOnByDefault;
		//get classloader so if we are in development mode, we will use that class loader for entities
		entityClassLoader = Thread.currentThread().getContextClassLoader();
		this.persistenceUnit = persistenceUnit2;
	}
	
	@Override
	protected void configure() {
		Multibinder uriBinder = Multibinder.newSetBinder(binder(), EntityLookup.class);
	    uriBinder.addBinding().to(HibernateLookup.class);
	}

	@Singleton
	@Provides
	public EntityManagerFactory providesSessionFactory(MeterRegistry metrics, Injector injector) throws IOException {
		boolean loadByClassMeta = loadByClassFile.get();
		String pu = persistenceUnit.get();
		EntityManagerFactory factory;
		if(loadByClassMeta) {
			factory = loadByClassMeta(pu, metrics, injector);
		} else {
			factory = createEntityMgrFromPuFile(pu);
		}
		
		return factory;
	}

	private EntityManagerFactory createEntityMgrFromPuFile(String pu) {
		log.info("Loading Hibernate from xml file.  ENTITY classloader="+entityClassLoader+" hibernate classloader="+this.getClass().getClassLoader()+" pu="+pu);

		Map properties = createClassLoaderProperty();		
		EntityManagerFactory factory = Persistence.createEntityManagerFactory(pu, properties );
		log.info("Done loading Hibernate");
		return factory;
	}

	private EntityManagerFactory loadByClassMeta(String clazz, MeterRegistry metrics, Injector injector) {
		log.info("Loading Hibernate from class meta.  ENTITY classloader="+entityClassLoader+" hibernate classloader="+this.getClass().getClassLoader()+" class="+clazz);

		Class loadClass = null;
		try {
			loadClass = entityClassLoader.loadClass(clazz);
			Object newInstance = injector.getInstance(loadClass);
			if(!(newInstance instanceof PersistenceUnitInfo))
				throw new IllegalArgumentException(clazz+" is not an instanceof PersistenceUnitInfo and must be");
		
			PersistenceUnitInfo info = (PersistenceUnitInfo) newInstance;
			//Can probably remove this proxy because overrideProperties should override BUT this needs lots of testing
			//on DevelopmentServer to make sure changes to code in many places don't break especially changing Dbo's
			PersistenceUnitInfo proxy = new PersistenceUnitInfoProxy(info, entityClassLoader);
			
			Map overrideProperties = createClassLoaderProperty();		
			
			return new HibernatePersistenceProvider().createContainerEntityManagerFactory(proxy, overrideProperties);
		} catch(ClassNotFoundException | SecurityException e) {
			throw new IllegalStateException("Could not construct DB settings", e);
		}
	}

	private Map createClassLoaderProperty() {
		Collection classLoaders = new ArrayList<>();
		classLoaders.add(entityClassLoader);
		Map properties = new HashMap<>();
		properties.put(AvailableSettings.CLASSLOADERS, classLoaders);
		return properties;
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy