/* JpaUtil.java {{IS_NOTE Purpose: Description: History: Mon Dec 17 2007, Created by jeffliu }}IS_NOTE Copyright (C) 2006 Potix Corporation. All Rights Reserved. {{IS_RIGHT }}IS_RIGHT */ package org.zkoss.zkplus.jpa; import java.util.HashMap; import java.util.Map; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.zkoss.zk.ui.Desktop; import org.zkoss.zk.ui.Execution; import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.UiException; import org.zkoss.zk.ui.WebApp; /** * This class is used to create and hold open EntityManagerFactory objects * within a Java EE environment. * <p>Applicable to EJB version 3.2.ga or later</p> * @author Jeff * @since 3.0.2 */ public class JpaUtil { private static final Logger log = LoggerFactory.getLogger(JpaUtil.class); public static final String CONFIG = "JpaUtil.PersistenceUnitName"; public static final String JPA_EMF_MAP = "org.zkoss.zkplus.jpa.EmfMap"; public static final String JPA_EM_MAP = "org.zkoss.zkplus.jpa.EmMap"; /* * Get the EntityManagerFactories Map from WebApp scope */ @SuppressWarnings("unchecked") private static Map<String, EntityManagerFactory> getEmfMap() { Map map = (Map) getWebApp().getAttribute(JPA_EMF_MAP); if (map == null) { map = new HashMap(); getWebApp().setAttribute(JPA_EMF_MAP, map); } return map; } /* * Get the EntityManagers Map from Execution scope */ @SuppressWarnings("unchecked") private static Map<String, EntityManager> getEmMap() { Execution current = Executions.getCurrent(); Map map = (Map) current.getAttribute(JPA_EM_MAP); if (map == null) { map = new HashMap(); Executions.getCurrent().setAttribute(JPA_EM_MAP, map); } return map; } /** * Create or return the default EntityManagerFactory as defined in zk.xml. * * <p> * In WEB-INF/zk.xml, add following lines: * * <pre><code> *<preference> * <name>JPA.PersistenceUnitName</name> * <value>PERSISTENCE_UNIT_NAME</value> *</preference> * </code></pre> * * </p> * * @return EntityManagerFactory */ public static EntityManagerFactory getEntityManagerFactory() { return initEntityManagerFactory(null, null); } /** * Create or return the EntityManagerFactory for the specified persistence * unit name. </br>*Notice:If the EntityManagerFactory with specified * persistence unit is not created yet, a new one will be created. * * @param puName Persistence unit name * @return EntityManagerFactory */ public static EntityManagerFactory getEntityManagerFactory(String puName) { return initEntityManagerFactory(puName, null); } /** * Create the EntityManagerFactory for the specified persistence unit and * defined properties. </br>*Notice: It always creates a new * EntityManagerFactory unless properties is null. * * @param puName Persistence unit name * @param properties Defined priorities * @return EntityManagerFactory */ public static EntityManagerFactory getEntityManagerFactory(String puName, Map properties) { return initEntityManagerFactory(puName, properties); } /** * Returns an EntityManager of the default EntityManagerFactory as defined in zk.xml in an Execution scope. * <p> * In WEB-INF/zk.xml, add following lines: * * <pre><code> *<preference> * <name>JPA.PersistenceUnitName</name> * <value>PERSISTENCE_UNIT_NAME</value> *</preference> * </code></pre> * * </p> * @return EntityManager */ public static EntityManager getEntityManager() { return initEntityManger(null, null); } /** * Returns or create an EntityManager for the specified persistence unit name. </br>*Notice:If * the EntityManagerFactory with specified persistence unit is not created * before, a new one will be created automatically. * <p>The EntityManager get by this method is guaranteed to be the same within one Execution for the * specified persistence unit name.</p> * * @param puName - * Persistence unit name * @return EntityManager */ public static EntityManager getEntityManager(String puName) { return initEntityManger(puName, null); } /** * Closes the EntityManager of the default EntityManagerFactory as * defined in zk.xml in an Execution scope. It is equals to * closeEntityManager(null). * <p> * In WEB-INF/zk.xml, add following lines: * * <pre><code> *<preference> * <name>JPA.PersistenceUnitName</name> * <value>PERSISTENCE_UNIT_NAME</value> *</preference> * </code></pre> * @since 3.0.7 */ public static void closeEntityManager() { closeEntityManager(null); } /** * Closes the EntityManager of the EntityManagerFactory of the specified puName; * @since 3.0.7 */ public static void closeEntityManager(String puName) { EntityManager em = getEmMap().remove(getPersistenceUnitName(puName)); if (em != null && em.isOpen()) em.close(); } /** * Returns an EntityManager for the specified persistence unit name and * defined properties. </br>*Notice: It always creates a new EntityManagerFactory * and thus a new EntityManager unless properties is null. * * @param puName - * Persistence unit name * @param properties - * Defined priorities * @return EntityManager */ public static EntityManager getEntiyManager(String puName, Map properties) { return initEntityManger(puName, properties); } /* * If EntityManagerFactory with persistence name puName is not found in Map, * created a new one and return; or return a new created EntityManagerFactory * directly. */ private static EntityManagerFactory initEntityManagerFactory(String puName, Map properties) { EntityManagerFactory emf; if (properties == null) { emf = getEmfMap().get(puName); if (emf == null) { emf = createEntityManagerFactory(puName, null); getEmfMap().put(puName, emf); } } else { emf = createEntityManagerFactory(puName, properties); getEmfMap().put(puName, emf); } return emf; } /* * If EntityManager with persistence name puName is not found in Map, * created a new one; or return the existing EntityManager of this execution directly. */ private static EntityManager initEntityManger(String puName, Map properties) { EntityManager em; if (properties == null) { String puName2 = getPersistenceUnitName(puName); em = getEmMap().get(puName2); if (em == null) { em = createEntityManager(puName, null); getEmMap().put(puName2, em); } } else { em = createEntityManager(puName, properties); getEmMap().put(getPersistenceUnitName(puName), em); } return em; } /* * Create the EntityManagerFactory by persistence unit name. If persistence * unit name not given, using the one which is defined in zk.xml */ private static EntityManagerFactory createEntityManagerFactory(String puName, Map properties) { puName = getPersistenceUnitName(puName); EntityManagerFactory emf; try { if (properties == null) { emf = Persistence.createEntityManagerFactory(puName); log.info("EntityManagerFactory for: " + puName + " is created "); } else { emf = Persistence.createEntityManagerFactory(puName, properties); log.info("EntityManagerFactory for: " + puName + " with properties " + properties + " is created "); } } catch (Exception ex) { log.error("Initial EntityManagerFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } getEmfMap().put(puName, emf); return emf; } /* * Create the EntityManager by persistence unit name. If persistence unit * name not given, using the one which is defined in zk.xml */ private static EntityManager createEntityManager(String puName, Map properties) { puName = getPersistenceUnitName(puName); EntityManager em = initEntityManagerFactory(puName, properties).createEntityManager(); return em; } private static WebApp getWebApp() { WebApp app = null; final Execution exec = Executions.getCurrent(); if (exec != null) { final Desktop desktop = exec.getDesktop(); if (desktop != null) { app = desktop.getWebApp(); } } return app; } private static String getPersistenceUnitName(String pu) { if (pu == null || pu.equals("")) { /* * Create EntityManagerFactory by preference in zk.xml */ final org.zkoss.zk.ui.util.Configuration config = getWebApp().getConfiguration(); pu = config.getPreference(CONFIG, null); } if (pu == null) { throw new UiException("Forget to specify the preference of " + CONFIG + " in WEB-INF/zk.xml?"); } return pu; } }