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