1 package ru.indvdum.jpa.dao
2 import java.sql.Connection
3 import java.sql.SQLException
4 import java.util.Map.Entry
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
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
25 import ru.indvdum.jpa.props.Props
28 * @author indvdum (gotoindvdum[at]gmail[dot]com)
29 * @since 08.11.2012 23:35:04
32 public class JPADataAccessObject {
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;
40 JPADataAccessObject() {
41 tx = em.getTransaction();
52 if(tx != null && tx.isActive()) {
58 if(tx != null && tx.isActive()) {
63 void detach(Object entity) {
67 protected static String getPersistenceUnitName() {
68 if (persistenceUnitName != null)
69 return persistenceUnitName;
71 if (persistenceUnitName == null)
72 persistenceUnitName = System.getProperty(Props.PERSISTANCE_UNIT_NAME_PROPERTY);
73 if (persistenceUnitName == null) {
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");
80 if (persistenceUnitName == null) {
81 XMLConfiguration conf = new XMLConfiguration("META-INF/persistence.xml");
82 persistenceUnitName = conf.getString("persistence-unit[@name]");
84 if (persistenceUnitName == null)
85 persistenceUnitName = "database";
86 return persistenceUnitName;
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();
96 public <T> T mergeAndRefresh(T object) {
97 def merged = em.merge(object)
103 public <T> T merge(T object) {
107 void refresh(Object ... refreshObjects) {
108 for(object in refreshObjects) {
113 boolean persist(Object ... persistanceQueue) {
114 persistAndRemove(persistanceQueue, new Object[0])
117 boolean persist(Collection entities) {
118 persistAndRemove(entities.toArray(), new Object[0])
121 boolean remove(Object ... removeQueue) {
122 persistAndRemove(new Object[0], removeQueue)
125 boolean remove(Collection entities) {
126 persistAndRemove(new Object[0], entities.toArray())
129 synchronized boolean persistAndRemove(Object[] persistanceQueue, Object[] removeQueue) {
133 if(persistanceQueue != null) {
134 for(object in persistanceQueue) {
141 if(removeQueue != null) {
142 for(object in removeQueue) {
150 log.error("Error while synchronizing with Database: ", t);
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());
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));
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));
182 query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
183 return em.createQuery(query).getResultList();
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;
195 return list(entityClass, fieldValues, null);
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();
205 public <T> T find(Class<T> entityClass, Object primaryKey) {
206 return em.find(entityClass, primaryKey);
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));
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));
228 query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
231 result = em.createQuery(query).getSingleResult();
232 } catch (NoResultException e) {
233 log.info("Object not found in Database: " + e.getMessage());
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;
247 return find(entityClass, fieldValues, null);
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();
258 public boolean contains(Collection entities) {
260 entities.each {res &= contains(it)}
264 public boolean contains(Object entity) {
265 return em.contains(entity);
268 private Object getSingleResult(Query query) {
270 return query.getSingleResult()
272 catch (NoResultException e) {