Replace load with findByUuid for delete with uuid(s) as argument.
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / ServiceBase.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.cdm.api.service;
12
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Set;
18 import java.util.UUID;
19
20 import org.apache.log4j.Logger;
21 import org.hibernate.LockOptions;
22 import org.hibernate.Session;
23 import org.springframework.context.ApplicationContext;
24 import org.springframework.context.ApplicationContextAware;
25 import org.springframework.dao.DataAccessException;
26 import org.springframework.transaction.annotation.Transactional;
27
28 import eu.etaxonomy.cdm.api.service.UpdateResult.Status;
29 import eu.etaxonomy.cdm.api.service.pager.Pager;
30 import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
31 import eu.etaxonomy.cdm.model.common.CdmBase;
32 import eu.etaxonomy.cdm.persistence.dao.common.ICdmEntityDao;
33 import eu.etaxonomy.cdm.persistence.query.Grouping;
34 import eu.etaxonomy.cdm.persistence.query.OrderHint;
35
36 public abstract class ServiceBase<T extends CdmBase, DAO extends ICdmEntityDao<T>> implements IService<T>, ApplicationContextAware {
37 @SuppressWarnings("unused")
38 private static final Logger logger = Logger.getLogger(ServiceBase.class);
39
40 //flush after saving this number of objects
41 int flushAfterNo = 2000;
42 protected ApplicationContext appContext;
43
44 protected DAO dao;
45
46 @Override
47 @Transactional(readOnly = true)
48 public void lock(T t, LockOptions lockOptions) {
49 dao.lock(t, lockOptions);
50 }
51
52 @Override
53 @Transactional(readOnly = true)
54 public void refresh(T t, LockOptions lockOptions, List<String> propertyPaths) {
55 dao.refresh(t, lockOptions, propertyPaths);
56 }
57
58 @Override
59 @Transactional(readOnly = false)
60 public void clear() {
61 dao.clear();
62 }
63
64 @Override
65 @Transactional(readOnly = true)
66 public int count(Class<? extends T> clazz) {
67 return dao.count(clazz);
68 }
69
70 @Override
71 @Transactional(readOnly = false)
72 public DeleteResult delete(UUID persistentObjectUUID) {
73 DeleteResult result = new DeleteResult();
74 try{
75 T persistentObject = dao.findByUuid(persistentObjectUUID);
76 dao.delete(persistentObject);
77 } catch(DataAccessException e){
78 result.setError();
79 result.addException(e);
80 }
81 return result;
82 }
83
84 @Override
85 @Transactional(readOnly = false)
86 public DeleteResult delete(Collection<UUID> persistentObjectUUIDs) {
87 DeleteResult result = new DeleteResult();
88 boolean atLeastOneOK = false;
89 for(UUID persistentObjectUUID : persistentObjectUUIDs) {
90 try {
91 T persistentObject = dao.findByUuid(persistentObjectUUID);
92 dao.delete(persistentObject);
93 } catch(DataAccessException e){
94 result.setStatus(Status.ERROR);
95 result.addException(e);
96 }
97 atLeastOneOK = true;
98 }
99
100 return result;
101 }
102
103 @Override
104 @Transactional(readOnly = false)
105 public DeleteResult delete(T persistentObject) {
106 DeleteResult result = new DeleteResult();
107 try{
108 dao.delete(persistentObject);
109 result.setCdmEntity(persistentObject);
110 } catch(DataAccessException e){
111 result.setError();
112 result.addException(e);
113 }
114 return result;
115 }
116
117
118
119 @Override
120 @Transactional(readOnly = true)
121 public boolean exists(UUID uuid) {
122 return dao.exists(uuid);
123 }
124
125 @Override
126 @Transactional(readOnly = true)
127 public List<T> find(Set<UUID> uuidSet) {
128 return dao.list(uuidSet, null, null, null, null);
129 }
130
131 @Override
132 @Transactional(readOnly = true)
133 public List<T> findById(Set<Integer> idSet) { //can't be called find(Set<Integer>) as this conflicts with find(Set<UUID)
134 return dao.listByIds(idSet, null, null, null, null);
135 }
136
137 @Override
138 @Transactional(readOnly = true)
139 public T find(UUID uuid) {
140 return uuid == null ? null : dao.findByUuid(uuid);
141 }
142
143 @Override
144 @Transactional(readOnly = true)
145 public T findWithoutFlush(UUID uuid) {
146 return uuid == null ? null : dao.findByUuidWithoutFlush(uuid);
147 }
148
149 @Override
150 @Transactional(readOnly = true)
151 public T find(int id) {
152 return dao.findById(id);
153 }
154
155 @Override
156 @Transactional(readOnly = true)
157 public Session getSession() {
158 return dao.getSession();
159 }
160
161 @Override
162 @Transactional(readOnly = true)
163 public List<Object[]> group(Class<? extends T> clazz,Integer limit, Integer start, List<Grouping> groups, List<String> propertyPaths) {
164 return dao.group(clazz, limit, start, groups, propertyPaths);
165 }
166
167 @Override
168 @Transactional(readOnly = true)
169 public <S extends T> List<S> list(Class<S> type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths){
170 return dao.list(type,limit, start, orderHints,propertyPaths);
171 }
172
173 @Override
174 @Transactional(readOnly = true)
175 public T load(UUID uuid) {
176 return uuid == null ? null : dao.load(uuid);
177 }
178
179 @Override
180 @Transactional(readOnly = true)
181 public T load(UUID uuid, List<String> propertyPaths){
182 return uuid == null ? null : dao.load(uuid, propertyPaths);
183 }
184
185 @Override
186 @Transactional(readOnly = false)
187 public T merge(T newInstance) {
188 return dao.merge(newInstance);
189 }
190
191 @Override
192 @Transactional(readOnly = false)
193 public List<T> merge(List<T> detachedObjects) {
194 List<T> mergedObjects = new ArrayList<T>();
195 for(T obj : detachedObjects) {
196 mergedObjects.add(dao.merge(obj));
197 }
198 return mergedObjects;
199 }
200
201 @Override
202 @Transactional(readOnly = true)
203 public <S extends T> Pager<S> page(Class<S> type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths){
204 Integer numberOfResults = dao.count(type);
205 List<S> results = new ArrayList<S>();
206 pageNumber = pageNumber == null ? 0 : pageNumber;
207 if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
208 Integer start = pageSize == null ? 0 : pageSize * pageNumber;
209 results = dao.list(type, pageSize, start, orderHints,propertyPaths);
210 }
211 return new DefaultPagerImpl<S>(pageNumber, numberOfResults, pageSize, results);
212 }
213
214 @Override
215 @Transactional(readOnly = true)
216 public UUID refresh(T persistentObject) {
217 return dao.refresh(persistentObject);
218 }
219
220 /**
221 * FIXME Candidate for harmonization
222 * is this method used, and if so, should it be exposed in the service layer?
223 * it seems a bit incongruous that we use an ORM to hide the fact that there is a
224 * database, then expose a method that talks about "rows" . . .
225 */
226 @Override
227 @Transactional(readOnly = true)
228 public List<T> rows(String tableName, int limit, int start) {
229 return dao.rows(tableName, limit, start);
230 }
231
232 @Override
233 @Transactional(readOnly = false)
234 public Map<UUID, T> save(Collection<T> newInstances) {
235 return dao.saveAll(newInstances);
236 }
237
238 @Override
239 @Transactional(readOnly = false)
240 public T save(T newInstance) {
241 return dao.save(newInstance);
242 }
243
244 @Override
245 @Transactional(readOnly = false)
246 public UUID saveOrUpdate(T transientObject) {
247 return dao.saveOrUpdate(transientObject);
248 }
249
250 @Override
251 @Transactional(readOnly = false)
252 public Map<UUID, T> saveOrUpdate(Collection<T> transientInstances) {
253 return dao.saveOrUpdateAll(transientInstances);
254 }
255
256 @Override
257 public void setApplicationContext(ApplicationContext appContext){
258 this.appContext = appContext;
259 }
260
261
262 protected abstract void setDao(DAO dao);
263
264 @Override
265 @Transactional(readOnly = false)
266 public UUID update(T transientObject) {
267 return dao.update(transientObject);
268 }
269
270 @Override
271 @Transactional(readOnly = true)
272 public List<T> list(T example, Set<String> includeProperties, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
273 return dao.list(example, includeProperties, limit, start, orderHints, propertyPaths);
274 }
275
276
277
278 }