IService, ServiceBase : added method findWithoutFlush
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / ServiceBase.java
index 7f22725ad9535272ded54a0155c7c010ede41d0d..6758293c41b63153cd100f76888f4e7254d52ce6 100644 (file)
@@ -1,8 +1,9 @@
+// $Id$\r
 /**\r
 * Copyright (C) 2007 EDIT\r
-* European Distributed Institute of Taxonomy \r
+* European Distributed Institute of Taxonomy\r
 * http://www.e-taxonomy.eu\r
-* \r
+*\r
 * The contents of this file are subject to the Mozilla Public License Version 1.1\r
 * See LICENSE.TXT at the top of this package for the full license terms.\r
 */\r
@@ -11,200 +12,213 @@ package eu.etaxonomy.cdm.api.service;
 \r
 import java.util.ArrayList;\r
 import java.util.Collection;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
 import java.util.List;\r
 import java.util.Map;\r
+import java.util.Set;\r
 import java.util.UUID;\r
 \r
 import org.apache.log4j.Logger;\r
-import org.springframework.beans.factory.annotation.Qualifier;\r
+import org.hibernate.LockMode;\r
+import org.hibernate.Session;\r
 import org.springframework.context.ApplicationContext;\r
 import org.springframework.context.ApplicationContextAware;\r
-import org.springframework.transaction.TransactionStatus;\r
 import org.springframework.transaction.annotation.Transactional;\r
 \r
+import eu.etaxonomy.cdm.api.service.exception.ReferencedObjectUndeletableException;\r
 import eu.etaxonomy.cdm.api.service.pager.Pager;\r
 import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;\r
 import eu.etaxonomy.cdm.model.common.CdmBase;\r
-import eu.etaxonomy.cdm.model.reference.ReferenceBase;\r
 import eu.etaxonomy.cdm.persistence.dao.common.ICdmEntityDao;\r
+import eu.etaxonomy.cdm.persistence.query.Grouping;\r
 import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
 \r
 public abstract class ServiceBase<T extends CdmBase, DAO extends ICdmEntityDao<T>> implements IService<T>, ApplicationContextAware {\r
-       private static final Logger logger = Logger.getLogger(ServiceBase.class);\r
-       \r
-       //flush after saving this number of objects\r
-       int flushAfterNo = 2000;\r
-       protected ApplicationContext appContext;\r
-\r
-       @Qualifier("baseDao")\r
-       protected DAO dao;\r
-\r
-       protected abstract void setDao(DAO dao);\r
-       \r
-       /* (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.api.service.Iyyy#setApplicationContext(org.springframework.context.ApplicationContext)\r
-        */\r
-       public void setApplicationContext(ApplicationContext appContext){\r
-               this.appContext = appContext;\r
-       }\r
-\r
-       public T getCdmObjectByUuid(UUID uuid) {\r
-               return dao.findByUuid(uuid);\r
-       }\r
-       \r
-       @Transactional(readOnly = true)\r
-       public <TYPE extends T> int count(Class<TYPE> clazz) {\r
-               return dao.count(clazz);\r
-       }\r
-       \r
-       @Transactional(readOnly = true)\r
-       public int count() {\r
-               return dao.count();\r
-       }\r
-\r
-       /**\r
-        * FIXME harmonise with saveOrUpdate\r
-        * @param cdmObj\r
-        * @return\r
-        */\r
-       @Transactional(readOnly = false)\r
-       protected UUID saveCdmObject(T cdmObj){\r
-               if (logger.isDebugEnabled()){logger.debug("Save cdmObj: " + (cdmObj == null? null: cdmObj.toString()));}\r
-               return dao.saveOrUpdate(cdmObj);\r
-       }\r
-       \r
-\r
-       /**\r
-        * FIXME harmonise with saveOrUpdate\r
-        * @param cdmObj\r
-        * @return\r
-        */\r
-       @Transactional(readOnly = false)\r
-       protected UUID saveCdmObject(T cdmObj, TransactionStatus txStatus){\r
-               // TODO: Implement with considering txStatus\r
-               if (logger.isDebugEnabled()){logger.debug("Save cdmObj: " + (cdmObj == null? null: cdmObj.toString()));}\r
-               return dao.saveOrUpdate(cdmObj);\r
-       }\r
-       \r
-       /**\r
-        * FIXME harmonise with saveAll\r
-        * @param <S>\r
-        * @param cdmObjCollection\r
-        * @return\r
-        */\r
-       @Transactional(readOnly = false)\r
-       protected <S extends T> Map<UUID, S> saveCdmObjectAll(Collection<? extends S> cdmObjCollection){\r
-               int types = cdmObjCollection.getClass().getTypeParameters().length;\r
-               if (types > 0){\r
-                       if (logger.isDebugEnabled()){logger.debug("ClassType: + " + cdmObjCollection.getClass().getTypeParameters()[0]);}\r
-               }\r
-               \r
-               Map<UUID, S> resultMap = new HashMap<UUID, S>();\r
-               Iterator<? extends S> iterator = cdmObjCollection.iterator();\r
-               int i = 0;\r
-                       while(iterator.hasNext()){\r
-                               if ( ( (i % 5000) == 0) && (i > 0)   ){logger.debug("Saved " + i + " objects" );}\r
-                               S cdmObj = iterator.next();\r
-                               UUID uuid = saveCdmObject(cdmObj);\r
-//                             if (logger.isDebugEnabled()){logger.debug("Save cdmObj: " + (cdmObj == null? null: cdmObj.toString()));}\r
-                               resultMap.put(uuid, cdmObj);\r
-                               i++;\r
-                               if ( (i % flushAfterNo) == 0){\r
-                                       try{\r
-                                                                       logger.debug("flush");\r
-                                       dao.flush();\r
-                                       }catch(Exception e){\r
-                                               logger.error("UUUIIIII");\r
-                                               e.printStackTrace();\r
-                                       }\r
-                               }\r
-                       }\r
-\r
-               if ( logger.isInfoEnabled() ){logger.info("Saved " + i + " objects" );}\r
-               return resultMap;\r
-       }\r
-\r
-       @Transactional(readOnly = false)\r
-       public UUID delete(T persistentObject) {\r
-               return dao.delete(persistentObject);\r
-       }\r
-\r
-       @Transactional(readOnly = true)\r
-       public boolean exists(UUID uuid) {\r
-               return dao.exists(uuid);\r
-       }\r
-\r
-       @Transactional(readOnly = true)\r
-       public T findByUuid(UUID uuid) {\r
-               return dao.findByUuid(uuid);\r
-       }\r
-\r
-       @Transactional(readOnly = true)\r
-       public <TYPE extends T> List<TYPE> list(Class<TYPE> type, int limit,int start) {\r
-               return dao.list(type, limit, start);\r
-       }\r
-       \r
-       @Transactional(readOnly = true)\r
-       public Pager<T> list(Integer pageSize, Integer pageNumber){\r
-               return list(pageSize, pageNumber, null);\r
-       }\r
-       \r
-       @Transactional (readOnly = true)\r
-       public Pager<T> list(Integer pageSize, Integer pageNumber, List<OrderHint> orderHints){\r
-               Integer numberOfResults = dao.count();\r
-               List<T> results = new ArrayList<T>();\r
-               if(numberOfResults > 0) { // no point checking again\r
-                       Integer start = pageSize == null ? 0 : pageSize * (pageNumber - 1);\r
-                       results = dao.list(pageSize, start, orderHints);\r
-               }\r
-               return new DefaultPagerImpl<T>(pageNumber, numberOfResults, pageSize, results);\r
-       }\r
-\r
-       @Transactional(readOnly = false)\r
-       public UUID save(T newInstance) {\r
-               return dao.save(newInstance);\r
-       }\r
-       \r
-       @Transactional(readOnly = false)\r
-       public Map<UUID, T> saveAll(Collection<T> newInstances) {\r
-               return dao.saveAll(newInstances);\r
-       }\r
-\r
-       @Transactional(readOnly = false)\r
-       public UUID saveOrUpdate(T transientObject) {\r
-               return dao.saveOrUpdate(transientObject);\r
-       }\r
-\r
-       @Transactional(readOnly = false)\r
-       public UUID update(T transientObject) {\r
-               return dao.update(transientObject);\r
-       }\r
-\r
-       @Transactional(readOnly = true)\r
-       public UUID refresh(T persistentObject) {\r
-               return dao.refresh(persistentObject);\r
-       }\r
-       \r
-       /**\r
-        * FIXME harmonise with delete()\r
-        * @param cdmObj\r
-        * @return\r
-        */\r
-       @Transactional(readOnly = false)\r
-       protected UUID removeCdmObject(T cdmObj){\r
-               if (logger.isDebugEnabled()){logger.debug("Save cdmObj: " + (cdmObj == null? null: cdmObj.toString()));}\r
-               return dao.delete(cdmObj);\r
-       }\r
-       \r
-       @Transactional(readOnly = true)\r
-       public List<T> list(int limit, int start) {\r
-               return dao.list(limit, start);\r
-       }\r
-\r
-       @Transactional(readOnly = true)\r
-       public List<T> rows(String tableName, int limit, int start) {\r
-               return dao.rows(tableName, limit, start);\r
-       }\r
+    @SuppressWarnings("unused")\r
+    private static final Logger logger = Logger.getLogger(ServiceBase.class);\r
+\r
+    //flush after saving this number of objects\r
+    int flushAfterNo = 2000;\r
+    protected ApplicationContext appContext;\r
+\r
+    protected DAO dao;\r
+\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public void lock(T t, LockMode lockMode) {\r
+        dao.lock(t, lockMode);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public void refresh(T t, LockMode lockMode, List<String> propertyPaths) {\r
+        dao.refresh(t, lockMode, propertyPaths);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = false)\r
+    public void clear() {\r
+        dao.clear();\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public int count(Class<? extends T> clazz) {\r
+        return dao.count(clazz);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = false)\r
+    public String delete(T persistentObject) {\r
+        return dao.delete(persistentObject).toString();\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public boolean exists(UUID uuid) {\r
+        return dao.exists(uuid);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public List<T> find(Set<UUID> uuidSet) {\r
+        return dao.list(uuidSet, null, null, null, null);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public List<T> findById(Set<Integer> idSet) {  //can't be called find(Set<Integer>) as this conflicts with find(Set<UUID)\r
+        return dao.listByIds(idSet, null, null, null, null);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public T find(UUID uuid) {\r
+        return dao.findByUuid(uuid);\r
+    }\r
+    \r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public T findWithoutFlush(UUID uuid) {\r
+        return dao.findByUuidWithoutFlush(uuid);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public T find(int id) {\r
+        return dao.findById(id);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public Session getSession() {\r
+        return dao.getSession();\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public List<Object[]> group(Class<? extends T> clazz,Integer limit, Integer start, List<Grouping> groups, List<String> propertyPaths) {\r
+        return dao.group(clazz, limit, start, groups, propertyPaths);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public <S extends T> List<S> list(Class<S> type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths){\r
+        return dao.list(type,limit, start, orderHints,propertyPaths);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public T load(UUID uuid) {\r
+        return dao.load(uuid);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public T load(UUID uuid, List<String> propertyPaths){\r
+        return dao.load(uuid, propertyPaths);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = false)\r
+    public T merge(T newInstance) {\r
+        return dao.merge(newInstance);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public  <S extends T> Pager<S> page(Class<S> type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths){\r
+        Integer numberOfResults = dao.count(type);\r
+        List<S> results = new ArrayList<S>();\r
+        pageNumber = pageNumber == null ? 0 : pageNumber;\r
+        if(numberOfResults > 0) { // no point checking again  //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)\r
+            Integer start = pageSize == null ? 0 : pageSize * pageNumber;\r
+            results = dao.list(type, pageSize, start, orderHints,propertyPaths);\r
+        }\r
+        return new DefaultPagerImpl<S>(pageNumber, numberOfResults, pageSize, results);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public UUID refresh(T persistentObject) {\r
+        return dao.refresh(persistentObject);\r
+    }\r
+\r
+    /**\r
+     * FIXME Candidate for harmonization\r
+     * is this method used, and if so, should it be exposed in the service layer?\r
+     * it seems a bit incongruous that we use an ORM to hide the fact that there is a\r
+     * database, then expose a method that talks about "rows" . . .\r
+     */\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public List<T> rows(String tableName, int limit, int start) {\r
+        return dao.rows(tableName, limit, start);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = false)\r
+    public Map<UUID, T> save(Collection<T> newInstances) {\r
+        return dao.saveAll(newInstances);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = false)\r
+    public UUID save(T newInstance) {\r
+        return dao.save(newInstance);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = false)\r
+    public UUID saveOrUpdate(T transientObject) {\r
+        return dao.saveOrUpdate(transientObject);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = false)\r
+    public Map<UUID, T> saveOrUpdate(Collection<T> transientInstances) {\r
+        return dao.saveOrUpdateAll(transientInstances);\r
+    }\r
+\r
+    @Override\r
+    public void setApplicationContext(ApplicationContext appContext){\r
+        this.appContext = appContext;\r
+    }\r
+\r
+\r
+    protected abstract void setDao(DAO dao);\r
+\r
+    @Override\r
+    @Transactional(readOnly = false)\r
+    public UUID update(T transientObject) {\r
+        return dao.update(transientObject);\r
+    }\r
+\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public List<T> list(T example, Set<String> includeProperties, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+        return dao.list(example, includeProperties, limit, start, orderHints, propertyPaths);\r
+    }\r
+    \r
+    \r
+\r
 }\r