18 package org.turro.jpa;
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.List;
24 import java.util.function.Consumer;
25 import java.util.regex.MatchResult;
26 import java.util.regex.Pattern;
27 import java.util.stream.Stream;
28 import javax.persistence.EntityManager;
29 import javax.persistence.EntityManagerFactory;
30 import javax.persistence.LockModeType;
31 import javax.persistence.NoResultException;
32 import javax.persistence.PersistenceUnitUtil;
33 import javax.persistence.Query;
34 import org.amic.util.string.MatchReplacer;
35 import org.turro.annotation.ElephantDao;
36 import org.turro.elephant.db.WhereClause;
37 import org.turro.jpa.entity.IDaoEntity;
38 import org.turro.jpa.query.AbstractJpaQuery;
39 import org.turro.jpa.query.JpaCriteriaDelete;
40 import org.turro.jpa.query.JpaCriteriaUpdate;
41 import org.turro.jpa.query.JpaQuery;
42 import org.turro.jpa.stream.DaoStream;
43 import org.turro.reflection.ClassNames;
44 import org.turro.reflection.Reflections;
45 import org.turro.sql.IDao;
46 import org.turro.sql.SqlClause;
52 public abstract class Dao implements IDao {
85 public <T> T find(Class<T> javaClass, Object arg) {
89 t = manager.find(javaClass, arg);
95 public <T> T find(Class<T> javaClass, Object arg, DaoCallback callback) {
98 try(DaoTransaction transaction =
new DaoTransaction(
this)) {
99 if(callback !=
null) {
100 callback.before(
null);
102 t = transaction.find(javaClass, arg);
103 if(callback !=
null) {
104 callback.after(
null, t);
111 public <T> T saveObject(T obj) {
112 try(DaoTransaction transaction =
new DaoTransaction(
this)) {
113 return transaction.saveObject(obj);
117 public <T extends IDaoEntity> T saveEntity(T entity) {
118 try(DaoTransaction transaction =
new DaoTransaction(
this)) {
119 if(!entity.isEmpty()) {
120 entity.prepareSave();
121 return transaction.saveObject(entity);
129 transaction.persist(obj);
136 if(!entity.isEmpty()) {
137 entity.prepareSave();
138 transaction.saveObject(entity);
150 for(Object obj : objs) {
151 if(callback !=
null) {
154 Object newObj = transaction.saveObject(obj);
155 if(callback !=
null) {
156 callback.
after(obj, newObj);
164 transaction.remove(transaction.saveObject(obj));
171 transaction.remove(transaction.saveObject(entity));
181 for(Object obj : objs) {
182 if(callback !=
null) {
185 transaction.remove(transaction.saveObject(obj));
186 if(callback !=
null) {
187 callback.
after(obj,
null);
196 entity.prepareDelete();
197 transaction.remove(transaction.saveObject(entity));
211 public boolean isLoaded(Object o, String attribute) {
212 PersistenceUnitUtil puu =
getFactory().getPersistenceUnitUtil();
213 return puu.isLoaded(o, attribute);
221 PersistenceUnitUtil puu =
getFactory().getPersistenceUnitUtil();
222 return puu.isLoaded(o);
229 public <T> List<T> getResultList(
JpaQuery<T> jpaQuery) {
230 return getResultList(jpaQuery, -1, -1);
233 public <T> List<T> getResultList(JpaQuery<T> jpaQuery,
int max) {
234 return getResultList(jpaQuery, -1, max);
237 public <T> List<T> getResultList(JpaQuery<T> jpaQuery,
int start,
int max) {
238 if(jpaQuery ==
null)
return Collections.EMPTY_LIST;
239 try(DaoManager manager =
new DaoManager(
this)) {
240 Query q = manager.createQuery(jpaQuery.query());
241 q.setLockMode(LockModeType.NONE);
242 if(start > 0) q.setFirstResult(start);
243 if(max > 0) q.setMaxResults(max);
244 return q.getResultList();
248 public <T> List<T> getResultList(Class<T> javaClass, String query) {
249 WhereClause wc =
new WhereClause();
251 return getResultList(javaClass, wc, -1, -1);
254 public <T> List<T> getResultList(Class<T> javaClass, String query,
int max) {
255 WhereClause wc =
new WhereClause();
257 return getResultList(javaClass, wc, -1, max);
260 public <T> List<T> getResultList(Class<T> javaClass, String query,
int start,
int max) {
261 WhereClause wc =
new WhereClause();
263 return getResultList(javaClass, wc, start, max);
266 public <T> List<T> getResultList(Class<T> javaClass, WhereClause wc) {
267 return getResultList(javaClass, wc, -1, -1);
270 public <T> List<T> getResultList(Class<T> javaClass, WhereClause wc,
int max) {
271 return getResultList(javaClass, wc, -1, max);
274 public <T> List<T> getResultList(Class<T> javaClass, WhereClause wc,
int start,
int max) {
275 if(wc ==
null)
return Collections.EMPTY_LIST;
276 try(DaoManager manager =
new DaoManager(
this)) {
277 Query q = manager.createQuery(wc.getClause(), javaClass);
278 q.setLockMode(LockModeType.NONE);
279 wc.setNamedParameters(q);
280 if(start > 0) q.setFirstResult(start);
281 if(max > 0) q.setMaxResults(max);
282 return q.getResultList();
287 public <T> List<T> getResultList(Class<T> javaClass, SqlClause sc) {
288 return getResultList(javaClass, sc, -1, -1);
292 public <T> List<T> getResultList(Class<T> javaClass, SqlClause sc,
int max) {
293 return getResultList(javaClass, sc, -1, max);
297 public <T> List<T> getResultList(Class<T> javaClass, SqlClause sc,
int start,
int max) {
298 if(sc ==
null)
return Collections.EMPTY_LIST;
299 try(DaoManager manager =
new DaoManager(
this)) {
300 Query q = manager.createQuery(sc.clause(), javaClass);
301 q.setLockMode(LockModeType.NONE);
302 manager.setNamedParameters(q, sc.getNamedValues());
303 if(start > 0) q.setFirstResult(start);
304 if(max > 0) q.setMaxResults(max);
305 return q.getResultList();
310 return getResultList(wc, -1, -1);
314 return getResultList(wc, -1, max);
318 if(wc ==
null)
return Collections.EMPTY_LIST;
323 if(!wc.
isUseNative()) q.setLockMode(LockModeType.NONE);
325 if(start > 0) q.setFirstResult(start);
326 if(max > 0) q.setMaxResults(max);
327 return q.getResultList();
333 return getResultList(sc, -1, -1);
338 return getResultList(sc, -1, max);
343 if(sc ==
null)
return Collections.EMPTY_LIST;
345 Query q = manager.createQuery(sc.clause());
346 q.setLockMode(LockModeType.NONE);
347 manager.setNamedParameters(q, sc.getNamedValues());
348 if(start > 0) q.setFirstResult(start);
349 if(max > 0) q.setMaxResults(max);
350 return q.getResultList();
355 return getResultList(query,
null);
359 return getResultList(query,
null, max);
363 return getResultList(query, pars, -1);
369 q.setLockMode(LockModeType.NONE);
370 if(max > 0) q.setMaxResults(max);
372 for(
int i = 0; i < pars.length; i++) {
373 q.setParameter(i + 1, pars[i]);
376 return q.getResultList();
383 manager.createNativeQuery(wc.
getClause()) :
385 if(!wc.
isUseNative()) q.setLockMode(LockModeType.NONE);
387 return q.getSingleResult();
394 Query q = manager.createQuery(sc.clause());
395 q.setLockMode(LockModeType.NONE);
396 manager.setNamedParameters(q, sc.getNamedValues());
397 return q.getSingleResult();
408 q.setLockMode(LockModeType.NONE);
410 for(
int i = 0; i < pars.length; i++) {
411 q.setParameter(i + 1, pars[i]);
414 return q.getSingleResult();
422 }
catch(NoResultException ex) {
430 }
catch(NoResultException ex) {
442 }
catch(NoResultException ex) {
455 for(
int i = 0; i < pars.length; i++) {
456 q.setParameter(i + 1, pars[i]);
459 return q.getSingleResult();
471 for(
int i = 0; i < pars.length; i++) {
472 q.setParameter(i + 1, pars[i]);
475 int res = q.executeUpdate();
481 List<JpaCriteriaDelete> list =
new ArrayList<>();
482 list.add(jpaCriteriaDelete);
486 public int executeDelete(Collection<JpaCriteriaDelete> jpaCriteriaDeletes) {
487 if(jpaCriteriaDeletes ==
null || jpaCriteriaDeletes.isEmpty())
return 0;
491 Query q = transaction.createQuery(jpaCriteriaDelete.delete());
492 res += q.executeUpdate();
499 List<JpaCriteriaUpdate> list =
new ArrayList<>();
500 list.add(jpaCriteriaUpdate);
504 public int executeUpdate(Collection<JpaCriteriaUpdate> jpaCriteriaUpdates) {
505 if(jpaCriteriaUpdates ==
null || jpaCriteriaUpdates.isEmpty())
return 0;
509 Query q = transaction.createQuery(jpaCriteriaUpdate.update());
510 res += q.executeUpdate();
518 Query q = transaction.createQuery(wc.
getClause());
520 int res = q.executeUpdate();
528 Query q = transaction.createQuery(sc.clause());
529 transaction.setNamedParameters(q, sc.getNamedValues());
530 int res = q.executeUpdate();
544 for(
int i = 0; i < pars.length; i++) {
545 q.setParameter(i + 1, pars[i]);
548 int res = q.executeUpdate();
555 public abstract String
getPath(Object
object);
560 public <T> T lazyLoader(Class<T> javaClass, Object proxy, String property) {
562 "select c from " + javaClass.getSimpleName() +
563 " c left join fetch c." + property +
" where c = ?",
564 new Object[] { proxy });
568 MatchReplacer replacer =
new MatchReplacer(Pattern.compile(
"\\?")) {
570 @Override
public String replacement(MatchResult m) {
574 return replacer.replace(query);
579 private Collection pool;
583 pool =
new ArrayList();
586 if(pool.size() >= poolSize) {
593 if(pool !=
null && pool.size() > 0) {
602 public <T> Stream<T> stream(Class<T> javaClass, String query) {
606 public <T> Stream<T> stream(Class<T> javaClass, String query,
int bacthSize) {
607 return new DaoStream<T>(
this, query).stream(bacthSize);
610 public <T> Stream<T> stream(Class<T> javaClass, WhereClause wc) {
611 return new DaoStream<T>(
this, wc).stream();
614 public <T> Stream<T> stream(Class<T> javaClass, WhereClause wc,
int bacthSize) {
615 return new DaoStream<T>(
this, wc).stream(bacthSize);
619 public <T> Stream<T> stream(Class<T> javaClass, SqlClause sc) {
620 return new DaoStream<T>(
this, sc).stream();
623 public <T> Stream<T> stream(Class<T> javaClass, SqlClause sc,
int bacthSize) {
624 return new DaoStream<T>(
this, sc).stream(bacthSize);
627 public <T> Stream<T> stream(Class<T> javaClass, AbstractJpaQuery<T> query) {
628 return new DaoStream<>(
this, query).stream();
631 public <T> Stream<T> stream(Class<T> javaClass, AbstractJpaQuery<T> query,
int bacthSize) {
632 return new DaoStream<>(
this, query).stream(bacthSize);
635 public <T>
void forEach(Class<T> javaClass, String query, Consumer<T> action) {
636 new DaoStream<T>(
this, query).forEach(action);
639 public <T>
void forEach(Class<T> javaClass, WhereClause wc, Consumer<T> action) {
640 new DaoStream<T>(
this, wc).forEach(action);
644 public <T>
void forEach(Class<T> javaClass, SqlClause sc, Consumer<T> action) {
645 new DaoStream<T>(
this, sc).forEach(action);
648 public <T>
void forEach(Class<T> javaClass, AbstractJpaQuery<T> query, Consumer<T> action) {
649 new DaoStream<>(
this, query).forEach(action);
655 for(String className : ClassNames.cached().byAnnotation(
ElephantDao.class.getName())) {
656 Class javaClass = Reflections.of(className).is(
Dao.class).returnClass();
657 if(javaClass !=
null) {
659 return (
Dao) Reflections.of(javaClass).instance();
void setNamedParameters(Query q)
List getResultList(SqlClause sc)
List getResultList(String query, Object[] pars)
List getResultList(WhereClause wc, int max)
List getResultList(String query, int max)
List getResultList(SqlClause sc, int start, int max)
int executeDelete(JpaCriteriaDelete jpaCriteriaDelete)
boolean isLoaded(Object o)
abstract EntityManager createCachedEntityManager()
Object getSingleResult(SqlClause sc)
int executeDelete(Collection< JpaCriteriaDelete > jpaCriteriaDeletes)
int executeUpdate(String query, Object[] pars)
abstract String getPath(Object object)
int executeUpdate(JpaCriteriaUpdate jpaCriteriaUpdate)
int executeUpdate(WhereClause wc)
List getResultList(String query, Object[] pars, int max)
Object getSingleNativeResult(String query)
void deleteObject(Object obj)
void persistObject(Object obj)
Object getSingleResultOrNull(WhereClause wc)
void deleteCollection(Collection objs, DaoCallback callback)
int executeNativeUpdate(String query, Object... pars)
Object getSingleResult(String query)
EntityManager getEntityManager()
Object getSingleNativeResult(String query, Object[] pars)
List getResultList(SqlClause sc, int max)
abstract EntityManagerFactory getFactory()
void deleteEntity(IDaoEntity entity)
int executeUpdate(String query)
boolean isLoaded(Object o, String attribute)
void saveCollection(Collection objs, DaoCallback callback)
List getResultList(String query)
boolean isNotLoaded(Object o)
int executeUpdate(SqlClause sc)
void saveCollection(Collection objs)
abstract EntityManager createEntityManager()
EntityManager getCachedEntityManager()
Query createNamedQuery(String name)
int executeUpdate(Collection< JpaCriteriaUpdate > jpaCriteriaUpdates)
void deleteCollection(Collection objs)
Object getSingleResult(WhereClause wc)
List getResultList(WhereClause wc, int start, int max)
Object getSingleResult(String query, Object[] pars)
Query createQuery(String query)
void poolObject(Object obj, int poolSize)
Object getSingleResultOrNull(SqlClause sc)
static String toJpaPositional(String query)
static Dao getDaoByPU(String pu)
Object getSingleResultOrNull(String query)
void deleteEntities(Collection< IDaoEntity > entities)
boolean isNotLoaded(Object o, String attribute)
List getResultList(WhereClause wc)
int executeNativeUpdate(SqlClause sc, Object... pars)
void saveEntities(Collection<? extends IDaoEntity > entities)
Object getSingleResultOrNull(String query, Object[] pars)
void before(Object value)
void after(Object oldValue, Object newValue)
default void prepareDelete()