3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
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.
11 package eu
.etaxonomy
.cdm
.api
.service
;
13 import java
.util
.ArrayList
;
14 import java
.util
.Collection
;
15 import java
.util
.List
;
18 import java
.util
.UUID
;
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
;
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
;
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);
40 //flush after saving this number of objects
41 int flushAfterNo
= 2000;
42 protected ApplicationContext appContext
;
47 @Transactional(readOnly
= true)
48 public void lock(T t
, LockOptions lockOptions
) {
49 dao
.lock(t
, lockOptions
);
53 @Transactional(readOnly
= true)
54 public void refresh(T t
, LockOptions lockOptions
, List
<String
> propertyPaths
) {
55 dao
.refresh(t
, lockOptions
, propertyPaths
);
59 @Transactional(readOnly
= false)
65 @Transactional(readOnly
= true)
66 public int count(Class
<?
extends T
> clazz
) {
67 return dao
.count(clazz
);
71 @Transactional(readOnly
= false)
72 public DeleteResult
delete(UUID persistentObjectUUID
) {
73 DeleteResult result
= new DeleteResult();
75 T persistentObject
= dao
.load(persistentObjectUUID
);
76 dao
.delete(persistentObject
);
77 } catch(DataAccessException e
){
79 result
.addException(e
);
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
) {
91 T persistentObject
= dao
.load(persistentObjectUUID
);
92 dao
.delete(persistentObject
);
93 } catch(DataAccessException e
){
94 result
.setStatus(Status
.ERROR
);
95 result
.addException(e
);
104 @Transactional(readOnly
= false)
105 public DeleteResult
delete(T persistentObject
) {
106 DeleteResult result
= new DeleteResult();
108 dao
.delete(persistentObject
);
109 result
.setCdmEntity(persistentObject
);
110 } catch(DataAccessException e
){
112 result
.addException(e
);
120 @Transactional(readOnly
= true)
121 public boolean exists(UUID uuid
) {
122 return dao
.exists(uuid
);
126 @Transactional(readOnly
= true)
127 public List
<T
> find(Set
<UUID
> uuidSet
) {
128 return dao
.list(uuidSet
, null, null, null, null);
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);
138 @Transactional(readOnly
= true)
139 public T
find(UUID uuid
) {
140 return uuid
== null ?
null : dao
.findByUuid(uuid
);
144 @Transactional(readOnly
= true)
145 public T
findWithoutFlush(UUID uuid
) {
146 return uuid
== null ?
null : dao
.findByUuidWithoutFlush(uuid
);
150 @Transactional(readOnly
= true)
151 public T
find(int id
) {
152 return dao
.findById(id
);
156 @Transactional(readOnly
= true)
157 public Session
getSession() {
158 return dao
.getSession();
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
);
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
);
174 @Transactional(readOnly
= true)
175 public T
load(UUID uuid
) {
176 return uuid
== null ?
null : dao
.load(uuid
);
180 @Transactional(readOnly
= true)
181 public T
load(UUID uuid
, List
<String
> propertyPaths
){
182 return uuid
== null ?
null : dao
.load(uuid
, propertyPaths
);
186 @Transactional(readOnly
= false)
187 public T
merge(T newInstance
) {
188 return dao
.merge(newInstance
);
192 @Transactional(readOnly
= true)
193 public <S
extends T
> Pager
<S
> page(Class
<S
> type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
){
194 Integer numberOfResults
= dao
.count(type
);
195 List
<S
> results
= new ArrayList
<S
>();
196 pageNumber
= pageNumber
== null ?
0 : pageNumber
;
197 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
198 Integer start
= pageSize
== null ?
0 : pageSize
* pageNumber
;
199 results
= dao
.list(type
, pageSize
, start
, orderHints
,propertyPaths
);
201 return new DefaultPagerImpl
<S
>(pageNumber
, numberOfResults
, pageSize
, results
);
205 @Transactional(readOnly
= true)
206 public UUID
refresh(T persistentObject
) {
207 return dao
.refresh(persistentObject
);
211 * FIXME Candidate for harmonization
212 * is this method used, and if so, should it be exposed in the service layer?
213 * it seems a bit incongruous that we use an ORM to hide the fact that there is a
214 * database, then expose a method that talks about "rows" . . .
217 @Transactional(readOnly
= true)
218 public List
<T
> rows(String tableName
, int limit
, int start
) {
219 return dao
.rows(tableName
, limit
, start
);
223 @Transactional(readOnly
= false)
224 public Map
<UUID
, T
> save(Collection
<T
> newInstances
) {
225 return dao
.saveAll(newInstances
);
229 @Transactional(readOnly
= false)
230 public UUID
save(T newInstance
) {
231 return dao
.save(newInstance
);
235 @Transactional(readOnly
= false)
236 public UUID
saveOrUpdate(T transientObject
) {
237 return dao
.saveOrUpdate(transientObject
);
241 @Transactional(readOnly
= false)
242 public Map
<UUID
, T
> saveOrUpdate(Collection
<T
> transientInstances
) {
243 return dao
.saveOrUpdateAll(transientInstances
);
247 public void setApplicationContext(ApplicationContext appContext
){
248 this.appContext
= appContext
;
252 protected abstract void setDao(DAO dao
);
255 @Transactional(readOnly
= false)
256 public UUID
update(T transientObject
) {
257 return dao
.update(transientObject
);
261 @Transactional(readOnly
= true)
262 public List
<T
> list(T example
, Set
<String
> includeProperties
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
263 return dao
.list(example
, includeProperties
, limit
, start
, orderHints
, propertyPaths
);