package com.sap.pto.adapters; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.sql.DataSource; import org.eclipse.persistence.config.PersistenceUnitProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This class is used for connection with the database(Persistence Service). * The SAP NetWeaver Cloud Persistence Service provides persistence in a relational * database for applications that are hosted on the SAP NetWeaver Cloud Platform. */ public class PersistenceAdapter { private static final Logger logger = LoggerFactory.getLogger(PersistenceAdapter.class); public static boolean REUSE_ENTITYMANAGER = false; public static boolean USE_JNDI = true; private static EntityManagerFactory emf; private static ThreadLocal<PersistenceContext> threadLocal = new PersistenceContext(); public static EntityManager getEntityManager() { if (USE_JNDI && emf == null) { try { InitialContext ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/DefaultDB"); String productName = ds.getConnection().getMetaData().getDatabaseProductName(); logger.info("Database Product Name: " + productName); Map<String, Object> properties = new HashMap<String, Object>(); properties.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, ds); // only activate driver if on HANA if ("HDB".equalsIgnoreCase(productName)) { logger.info("Activating HANA driver"); properties.put("eclipselink.target-database", "com.sap.persistence.platform.database.HDBPlatform"); } emf = Persistence.createEntityManagerFactory("pto", properties); logger.info("EntityManagerFactory created through JNDI lookup."); } catch (NamingException e) { logger.error("JNDI DataSource could not be found.", e); } catch (SQLException e) { logger.error("Could not determine database type."); } } if (REUSE_ENTITYMANAGER) { return threadLocal.get().getEntityManager(); } else { return emf.createEntityManager(); } } public static void releaseEntityManager() { threadLocal.get().remove(); } public static synchronized void setService(EntityManagerFactory emFactory) { emf = emFactory; } public static synchronized void unsetService(EntityManagerFactory emFactory) { emf = null; } public static synchronized EntityManagerFactory getService() { return emf; } public static boolean beginTransactionOnDemand(EntityManager em) { boolean closeTransaction = false; if (!em.getTransaction().isActive()) { em.getTransaction().begin(); closeTransaction = true; } return closeTransaction; } public static void commitTransactionOnDemand(EntityManager em, boolean closeTransaction) { if (closeTransaction && em.getTransaction().isActive()) { try { em.getTransaction().commit(); } finally { if (!REUSE_ENTITYMANAGER && em.isOpen()) { em.close(); } } } } public static void clearCache() { emf.getCache().evictAll(); } private static class PersistenceContext extends ThreadLocal<PersistenceContext> { private static Logger logger = LoggerFactory.getLogger(PersistenceContext.class); private EntityManager em = null; @Override public PersistenceContext initialValue() { try { this.em = emf.createEntityManager(); } catch (Exception e) { logger.warn(Thread.currentThread().getName() + " cannot obtain EntityManagerFactory yet.", e); } return this; } public EntityManager getEntityManager() { if (this.em == null) { this.em = emf.createEntityManager(); } return this.em; } @Override public void remove() { if (this.em != null && this.em.isOpen()) { this.em.close(); } this.em = null; } } }