src/main/java/ru/indvdum/jpa/dao/JPADataAccessObject.groovy
author indvdum (gotoindvdum[at]gmail[dot]com)
Sun, 25 Nov 2012 03:14:01 +0400
changeset 16 409046072775
parent 13 bfcb605c25ef
child 19 39381427da3f
permissions -rw-r--r--
Moar data access methods
     1 package ru.indvdum.jpa.dao
     2 import java.sql.Connection
     3 import java.sql.SQLException
     4 import java.util.Map.Entry
     5 
     6 import javax.persistence.EntityManager
     7 import javax.persistence.EntityManagerFactory
     8 import javax.persistence.EntityTransaction
     9 import javax.persistence.NoResultException
    10 import javax.persistence.Persistence
    11 import javax.persistence.Query
    12 import javax.persistence.criteria.CriteriaBuilder
    13 import javax.persistence.criteria.CriteriaQuery
    14 import javax.persistence.criteria.Predicate
    15 import javax.persistence.criteria.Root
    16 import javax.sql.DataSource
    17 
    18 import org.apache.commons.configuration.XMLConfiguration
    19 import org.apache.openjpa.conf.OpenJPAConfiguration
    20 import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI
    21 import org.apache.openjpa.persistence.OpenJPAPersistence
    22 import org.slf4j.Logger
    23 import org.slf4j.LoggerFactory
    24 
    25 import ru.indvdum.jpa.props.Props
    26 
    27 /**
    28  * @author indvdum (gotoindvdum[at]gmail[dot]com)
    29  * @since 08.11.2012 23:35:04
    30  *
    31  */
    32 public class JPADataAccessObject {
    33 
    34 	protected static Logger log = LoggerFactory.getLogger(JPADataAccessObject.class.getSimpleName());
    35 	protected static String persistenceUnitName = null;
    36 	protected static EntityManagerFactory emf = Persistence.createEntityManagerFactory(getPersistenceUnitName(), JPAPropertySelector.select());
    37 	protected EntityManager em = emf.createEntityManager();
    38 	protected EntityTransaction tx = null;
    39 
    40 	JPADataAccessObject() {
    41 		tx = em.getTransaction();
    42 		tx.begin();
    43 	}
    44 
    45 	void close() {
    46 		commit()
    47 		em.close()
    48 		em = null
    49 	}
    50 
    51 	void commit() {
    52 		if(tx != null && tx.isActive()) {
    53 			tx.commit()
    54 		}
    55 	}
    56 
    57 	void rollback() {
    58 		if(tx != null && tx.isActive()) {
    59 			tx.rollback()
    60 		}
    61 	}
    62 
    63 	void detach(Object entity) {
    64 		em.detach(entity);
    65 	}
    66 
    67 	protected static String getPersistenceUnitName() {
    68 		if (persistenceUnitName != null)
    69 			return persistenceUnitName;
    70 
    71 		if (persistenceUnitName == null)
    72 			persistenceUnitName = System.getProperty(Props.PERSISTANCE_UNIT_NAME_PROPERTY);
    73 		if (persistenceUnitName == null) {
    74 			try {
    75 				persistenceUnitName = ResourceBundle.getBundle(Props.JPADAO_PROPERTY_FILE).getString(Props.PERSISTANCE_UNIT_NAME_PROPERTY);
    76 			} catch (MissingResourceException e) {
    77 				log.info("Configuration file " + Props.JPADAO_PROPERTY_FILE + ".properties not found");
    78 			}
    79 		}
    80 		if (persistenceUnitName == null) {
    81 			XMLConfiguration conf = new XMLConfiguration("META-INF/persistence.xml");
    82 			persistenceUnitName = conf.getString("persistence-unit[@name]");
    83 		}
    84 		if (persistenceUnitName == null)
    85 			persistenceUnitName = "database";
    86 		return persistenceUnitName;
    87 	}
    88 
    89 	public static Connection getSQLConnection() throws SQLException {
    90 		OpenJPAEntityManagerFactorySPI openjpaemf = (OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(emf);
    91 		OpenJPAConfiguration conf = openjpaemf.getConfiguration();
    92 		DataSource ds = (DataSource) conf.getConnectionFactory();
    93 		return ds.getConnection();
    94 	}
    95 
    96 	public <T> T mergeAndRefresh(T object) {
    97 		def merged = em.merge(object)
    98 		em.refresh(merged)
    99 
   100 		merged
   101 	}
   102 
   103 	public <T> T merge(T object) {
   104 		em.merge(object)
   105 	}
   106 
   107 	void refresh(Object ... refreshObjects) {
   108 		for(object in refreshObjects) {
   109 			em.refresh(object)
   110 		}
   111 	}
   112 
   113 	boolean persist(Object ... persistanceQueue) {
   114 		persistAndRemove(persistanceQueue, new Object[0])
   115 	}
   116 
   117 	boolean persist(Collection entities) {
   118 		persistAndRemove(entities.toArray(), new Object[0])
   119 	}
   120 
   121 	boolean remove(Object ... removeQueue) {
   122 		persistAndRemove(new Object[0], removeQueue)
   123 	}
   124 
   125 	boolean remove(Collection entities) {
   126 		persistAndRemove(new Object[0], entities.toArray())
   127 	}
   128 
   129 	synchronized boolean persistAndRemove(Object[] persistanceQueue, Object[] removeQueue) {
   130 
   131 		try {
   132 
   133 			if(persistanceQueue != null) {
   134 				for(object in persistanceQueue) {
   135 					if(object != null) {
   136 						em.persist(object)
   137 					}
   138 				}
   139 			}
   140 
   141 			if(removeQueue != null) {
   142 				for(object in removeQueue) {
   143 					if(object != null) {
   144 						em.remove(object)
   145 					}
   146 				}
   147 			}
   148 		}
   149 		catch(Throwable t) {
   150 			log.error("Error while synchronizing with Database: ", t);
   151 			return false;
   152 		}
   153 
   154 		return true
   155 	}
   156 
   157 	public <T> List<T> list(Class<T> entityClass) {
   158 		CriteriaQuery<T> query = em.getCriteriaBuilder().createQuery(entityClass);
   159 		query.from(entityClass);
   160 		return new ArrayList(em.createQuery(query).getResultList());
   161 	}
   162 
   163 	public <T> List<T> list(Class<T> entityClass, Map<String, Object> equalProperties, Map<String, Object> notEqualProperties) {
   164 		CriteriaBuilder cb = em.getCriteriaBuilder();
   165 		CriteriaQuery<T> query = cb.createQuery(entityClass);
   166 		Root<T> root = query.from(entityClass);
   167 		Collection<Predicate> predicates = new HashSet<Predicate>();
   168 		if(equalProperties != null) {
   169 			for(Entry<String, Object> entry: equalProperties.entrySet()){
   170 				String property = entry.getKey();
   171 				Object value = entry.getValue();
   172 				predicates.add(cb.equal(root.get(property), value));
   173 			}
   174 		}
   175 		if(notEqualProperties != null) {
   176 			for(Entry<String, Object> entry: equalProperties.entrySet()){
   177 				String property = entry.getKey();
   178 				Object value = entry.getValue();
   179 				predicates.add(cb.notEqual(root.get(property), value));
   180 			}
   181 		}
   182 		query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
   183 		return em.createQuery(query).getResultList();
   184 	}
   185 
   186 	public <T> List<T> list(Class<T> entityClass, Object ... equalFieldNamesAndValues) {
   187 		if (equalFieldNamesAndValues.length % 2 != 0)
   188 			throw new RuntimeException("Illegal arguments count: ${equalFieldNamesAndValues.length}");
   189 		Map fieldValues = [:];
   190 		for (int i = 0; i < equalFieldNamesAndValues.length;) {
   191 			String field = (String) equalFieldNamesAndValues[i++];
   192 			Object value = equalFieldNamesAndValues[i++];
   193 			fieldValues["${field}"] = value;
   194 		}
   195 		return list(entityClass, fieldValues, null);
   196 	}
   197 
   198 	public List list(String jpql, Object ... paramValues) {
   199 		Query query = em.createQuery(jpql);
   200 		for (int i = 0; i < paramValues.length; i++)
   201 			query.setParameter(i + 1, paramValues[i]);
   202 		return query.getResultList();
   203 	}
   204 
   205 	public <T> T find(Class<T> entityClass, Object primaryKey) {
   206 		return em.find(entityClass, primaryKey);
   207 	}
   208 
   209 	public <T> T find(Class<T> entityClass, Map<String, Object> equalProperties, Map<String, Object> notEqualProperties) {
   210 		CriteriaBuilder cb = em.getCriteriaBuilder();
   211 		CriteriaQuery<T> query = cb.createQuery(entityClass);
   212 		Root<T> root = query.from(entityClass);
   213 		Collection<Predicate> predicates = new HashSet<Predicate>();
   214 		if(equalProperties != null) {
   215 			for(Entry<String, Object> entry: equalProperties.entrySet()){
   216 				String property = entry.getKey();
   217 				Object value = entry.getValue();
   218 				predicates.add(cb.equal(root.get(property), value));
   219 			}
   220 		}
   221 		if(notEqualProperties != null) {
   222 			for(Entry<String, Object> entry: equalProperties.entrySet()){
   223 				String property = entry.getKey();
   224 				Object value = entry.getValue();
   225 				predicates.add(cb.notEqual(root.get(property), value));
   226 			}
   227 		}
   228 		query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
   229 		T result = null;
   230 		try {
   231 			result = em.createQuery(query).getSingleResult();
   232 		} catch (NoResultException e) {
   233 			log.info("Object not found in Database: " + e.getMessage());
   234 		}
   235 		return result;
   236 	}
   237 
   238 	public <T> T find(Class<T> entityClass, Object ... equalFieldNamesAndValues) {
   239 		if (equalFieldNamesAndValues.length % 2 != 0)
   240 			throw new RuntimeException("Illegal arguments count: ${equalFieldNamesAndValues.length}");
   241 		Map fieldValues = [:];
   242 		for (int i = 0; i < equalFieldNamesAndValues.length;) {
   243 			String field = (String) equalFieldNamesAndValues[i++];
   244 			Object value = equalFieldNamesAndValues[i++];
   245 			fieldValues["${field}"] = value;
   246 		}
   247 		return find(entityClass, fieldValues, null);
   248 	}
   249 	
   250 	
   251 	public Object find(String jpql, Object ... paramValues) {
   252 		Query query = em.createQuery(jpql);
   253 		for (int i = 0; i < paramValues.length; i++)
   254 			query.setParameter(i + 1, paramValues[i]);
   255 		return query.getSingleResult();
   256 	}
   257 
   258 	public boolean contains(Collection entities) {
   259 		boolean res = true;
   260 		entities.each {res &= contains(it)}
   261 		return res
   262 	}
   263 
   264 	public boolean contains(Object entity) {
   265 		return em.contains(entity);
   266 	}
   267 
   268 	private Object getSingleResult(Query query) {
   269 		try {
   270 			return query.getSingleResult()
   271 		}
   272 		catch (NoResultException e) {
   273 			return null
   274 		}
   275 	}
   276 }