2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.cdm
.persistence
.dao
.hibernate
.common
;
12 import java
.util
.Collection
;
13 import java
.util
.HashMap
;
14 import java
.util
.Iterator
;
15 import java
.util
.List
;
17 import java
.util
.UUID
;
19 import org
.apache
.log4j
.Logger
;
20 import org
.apache
.lucene
.search
.Sort
;
21 import org
.apache
.lucene
.search
.SortField
;
22 import org
.hibernate
.Criteria
;
23 import org
.hibernate
.HibernateException
;
24 import org
.hibernate
.NonUniqueObjectException
;
25 import org
.hibernate
.Query
;
26 import org
.hibernate
.Session
;
27 import org
.hibernate
.criterion
.Order
;
28 import org
.hibernate
.criterion
.Projections
;
29 import org
.hibernate
.criterion
.Restrictions
;
30 import org
.hibernate
.envers
.query
.AuditQuery
;
31 import org
.hibernate
.search
.FullTextQuery
;
32 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
33 import org
.springframework
.beans
.factory
.annotation
.Qualifier
;
34 import org
.springframework
.dao
.DataAccessException
;
35 import org
.springframework
.stereotype
.Repository
;
37 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
38 import eu
.etaxonomy
.cdm
.persistence
.dao
.BeanInitializer
;
39 import eu
.etaxonomy
.cdm
.persistence
.dao
.common
.ICdmEntityDao
;
40 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
;
45 * FIXME CdmEntityDaoBase is abstract, can it be annotated with @Repository?
48 public abstract class CdmEntityDaoBase
<T
extends CdmBase
> extends DaoBase
implements ICdmEntityDao
<T
> {
49 private static final Logger logger
= Logger
.getLogger(CdmEntityDaoBase
.class);
51 int flushAfterNo
= 1000; //large numbers may cause synchronisation errors when commiting the session !!
52 protected Class
<T
> type
;
55 @Qualifier("defaultBeanInitializer")
56 protected BeanInitializer defaultBeanInitializer
;
59 public CdmEntityDaoBase(Class
<T
> type
){
61 logger
.debug("Creating DAO of type [" + type
.getSimpleName() + "]");
64 //TODO this method should be moved to a concrete class (not typed)
65 public UUID
saveCdmObj(CdmBase cdmObj
) throws DataAccessException
{
66 getSession().saveOrUpdate(cdmObj
);
67 return cdmObj
.getUuid();
70 //TODO: Replace saveCdmObj() by saveCdmObject_
71 private UUID
saveCdmObject_(T cdmObj
){
72 getSession().saveOrUpdate(cdmObj
);
73 return cdmObj
.getUuid();
76 //TODO: Use everywhere CdmEntityDaoBase.saveAll() instead of ServiceBase.saveCdmObjectAll()?
77 public Map
<UUID
, T
> saveAll(Collection
<T
> cdmObjCollection
){
78 int types
= cdmObjCollection
.getClass().getTypeParameters().length
;
80 if (logger
.isDebugEnabled()){logger
.debug("ClassType: + " + cdmObjCollection
.getClass().getTypeParameters()[0]);}
83 Map
<UUID
, T
> resultMap
= new HashMap
<UUID
, T
>();
84 Iterator
<T
> iterator
= cdmObjCollection
.iterator();
86 while(iterator
.hasNext()){
87 if ( ( (i
% 2000) == 0) && (i
> 0) ){logger
.debug("Saved " + i
+ " objects" );}
88 T cdmObj
= iterator
.next();
89 UUID uuid
= saveCdmObject_(cdmObj
);
90 if (logger
.isDebugEnabled()){logger
.debug("Save cdmObj: " + (cdmObj
== null?
null: cdmObj
.toString()));}
91 resultMap
.put(uuid
, cdmObj
);
93 if ( (i
% flushAfterNo
) == 0){
95 logger
.debug("flush");
98 logger
.error("UUUIIIII");
104 if ( logger
.isInfoEnabled() ){logger
.info("Saved " + i
+ " objects" );}
109 public UUID
saveOrUpdate(T transientObject
) throws DataAccessException
{
111 if (logger
.isDebugEnabled()){logger
.debug("dao saveOrUpdate start...");}
112 if (logger
.isDebugEnabled()){logger
.debug("transientObject(" + transientObject
.getClass().getSimpleName() + ") ID:" + transientObject
.getId() + ", UUID: " + transientObject
.getUuid()) ;}
113 Session session
= getSession();
114 session
.saveOrUpdate(transientObject
);
115 if (logger
.isDebugEnabled()){logger
.debug("dao saveOrUpdate end");}
116 return transientObject
.getUuid();
117 } catch (NonUniqueObjectException e
) {
118 logger
.error("Error in CdmEntityDaoBase.saveOrUpdate(obj)");
119 logger
.error(e
.getIdentifier());
120 logger
.error(e
.getEntityName());
121 logger
.error(e
.getMessage());
124 } catch (HibernateException e
) {
131 public UUID
save(T newInstance
) throws DataAccessException
{
132 getSession().save(newInstance
);
133 return newInstance
.getUuid();
136 public UUID
update(T transientObject
) throws DataAccessException
{
137 getSession().update(transientObject
);
138 return transientObject
.getUuid();
141 public UUID
refresh(T persistentObject
) throws DataAccessException
{
142 getSession().refresh(persistentObject
);
143 return persistentObject
.getUuid();
146 public UUID
delete(T persistentObject
) throws DataAccessException
{
147 getSession().delete(persistentObject
);
148 return persistentObject
.getUuid();
151 public T
findById(int id
) throws DataAccessException
{
152 return (T
) getSession().get(type
, id
);
155 public T
findByUuid(UUID uuid
) throws DataAccessException
{
156 Session session
= getSession();
157 Criteria crit
= session
.createCriteria(type
);
158 crit
.add(Restrictions
.eq("uuid", uuid
));
159 crit
.addOrder(Order
.desc("created"));
160 List
<T
> results
= crit
.list();
161 if (results
.isEmpty()){
164 return results
.get(0);
168 public T
load(UUID uuid
) {
169 T bean
= findByUuid(uuid
);
172 defaultBeanInitializer
.load(bean
);
178 public T
load(UUID uuid
, List
<String
> propertyPaths
){
179 T bean
= findByUuid(uuid
);
183 defaultBeanInitializer
.initialize(bean
, propertyPaths
);
188 public Boolean
exists(UUID uuid
) {
189 if (findByUuid(uuid
)==null){
199 public <TYPE
extends T
> int count(Class
<TYPE
> type
) {
200 Session session
= getSession();
201 Criteria crit
= session
.createCriteria(type
);
202 crit
.setProjection(Projections
.projectionList().add(Projections
.rowCount()));
203 Integer nbrRows
= (Integer
) crit
.uniqueResult();
204 return nbrRows
.intValue();
207 public List
<T
> list(Integer limit
, Integer start
) {
208 return list(limit
, start
, null);
211 protected void addOrder(Criteria criteria
, List
<OrderHint
> orderHints
) {
212 if(orderHints
!= null){
213 for(OrderHint orderHint
: orderHints
){
215 String assocObj
= null, propname
;
217 if((pos
= orderHint
.getPropertyName().indexOf('.', 0)) >= 0){
218 assocObj
= orderHint
.getPropertyName().substring(0, pos
);
219 propname
= orderHint
.getPropertyName().substring(pos
+ 1);
221 propname
= orderHint
.getPropertyName();
223 if(orderHint
.isAscending()){
224 order
= Order
.asc(propname
);
226 order
= Order
.desc(propname
);
228 if(assocObj
!= null){
229 criteria
.createCriteria(assocObj
).addOrder(order
);
231 criteria
.addOrder(order
);
237 protected void addOrder(FullTextQuery fullTextQuery
, List
<OrderHint
> orderHints
) {
238 if(orderHints
!= null && !orderHints
.isEmpty()) {
239 org
.apache
.lucene
.search
.Sort sort
= new Sort();
240 SortField
[] sortFields
= new SortField
[orderHints
.size()];
241 for(int i
= 0; i
< orderHints
.size(); i
++) {
242 OrderHint orderHint
= orderHints
.get(i
);
243 switch(orderHint
.getSortOrder()) {
245 sortFields
[i
] = new SortField(orderHint
.getPropertyName() + "_forSort", false);
247 sortFields
[i
] = new SortField(orderHint
.getPropertyName() + "_forSort",true);
250 sort
.setSort(sortFields
);
251 fullTextQuery
.setSort(sort
);
255 public List
<T
> list(Integer limit
, Integer start
, List
<OrderHint
> orderHints
) {
256 return list(limit
,start
,orderHints
,null);
259 public List
<T
> list(Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
260 Criteria criteria
= getSession().createCriteria(type
);
262 criteria
.setFirstResult(start
);
263 criteria
.setMaxResults(limit
);
266 addOrder(criteria
,orderHints
);
267 List
<T
> results
= (List
<T
>)criteria
.list();
269 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
273 public <TYPE
extends T
> List
<TYPE
> list(Class
<TYPE
> type
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
274 Criteria crit
= getSession().createCriteria(type
);
276 crit
.setFirstResult(start
);
277 crit
.setMaxResults(limit
);
280 addOrder(crit
,orderHints
);
282 List
<TYPE
> results
= (List
<TYPE
>)crit
.list();
283 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
287 public <TYPE
extends T
> List
<TYPE
> list(Class
<TYPE
> type
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
) {
288 return list(type
,limit
,start
,orderHints
,null);
291 public <TYPE
extends T
> List
<TYPE
> list(Class
<TYPE
> type
, Integer limit
, Integer start
) {
292 return list(type
,limit
,start
,null,null);
295 public List
<T
> rows(String tableName
, int limit
, int start
) {
296 Query query
= getSession().createQuery("from " + tableName
+ " order by uuid");
297 query
.setFirstResult(start
);
298 query
.setMaxResults(limit
);
299 List
<T
> result
= query
.list();
303 public Class
<T
> getType() {
307 protected void setPagingParameter(Query query
, Integer pageSize
, Integer pageNumber
){
308 if(pageSize
!= null) {
309 query
.setMaxResults(pageSize
);
310 if(pageNumber
!= null) {
311 query
.setFirstResult(pageNumber
* pageSize
);
313 query
.setFirstResult(0);
318 protected void setPagingParameter(AuditQuery query
, Integer pageSize
, Integer pageNumber
){
319 if(pageSize
!= null) {
320 query
.setMaxResults(pageSize
);
321 if(pageNumber
!= null) {
322 query
.setFirstResult(pageNumber
* pageSize
);
324 query
.setFirstResult(0);