View Javadoc

1   /*
2    * EL4J, the Extension Library for the J2EE, adds incremental enhancements to
3    * the spring framework, http://el4j.sf.net
4    * Copyright (C) 2005 by ELCA Informatique SA, Av. de la Harpe 22-24,
5    * 1000 Lausanne, Switzerland, http://www.elca.ch
6    *
7    * EL4J is published under the GNU Lesser General Public License (LGPL)
8    * Version 2.1. See http://www.gnu.org/licenses/
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU Lesser General Public License for more details.
14   *
15   * For alternative licensing, please contact info@elca.ch
16   */
17  package ch.elca.el4j.services.persistence.jpa.dao;
18  
19  import java.io.Serializable;
20  import java.util.Collection;
21  import java.util.List;
22  
23  import javax.persistence.criteria.CriteriaQuery;
24  
25  import org.hibernate.criterion.DetachedCriteria;
26  import org.springframework.dao.DataAccessException;
27  import org.springframework.dao.DataIntegrityViolationException;
28  import org.springframework.dao.DataRetrievalFailureException;
29  import org.springframework.dao.OptimisticLockingFailureException;
30  
31  import ch.elca.el4j.services.persistence.generic.dao.ConvenienceGenericDao;
32  import ch.elca.el4j.services.persistence.generic.dao.annotations.ReturnsUnchangedParameter;
33  import ch.elca.el4j.services.persistence.hibernate.dao.extent.DataExtent;
34  import ch.elca.el4j.services.persistence.jpa.criteria.QueryBuilder;
35  
36  /**
37   * This interface extends {@link ConvenienceGenericDao} with query methods using
38   * {@link CriteriaQuery}s.
39   *
40   * @svnLink $Revision: 4253 $;$Date: 2010-12-21 11:08:04 +0100 (Di, 21. Dez 2010) $;$Author: swismer $;$URL: https://el4j.svn.sourceforge.net/svnroot/el4j/branches/el4j_3_1/el4j/framework/modules/hibernate/src/main/java/ch/elca/el4j/services/persistence/jpa/dao/ConvenienceGenericJpaDao.java $
41   *
42   * @param <T>     the domain object type
43   * @param <ID>    the id of the domain object to find
44   *
45   * @author Simon Stelling (SST)
46   */
47  // TODO: javadoc review.
48  public interface ConvenienceGenericJpaDao<T, ID extends Serializable> {
49  	
50  	// begin GenericDao part
51  	
52  	/**
53  	 *  Needed because the Java generics throw away this type
54  	 *  information.
55  	 * @return Returns the domain class this DAO is responsible for.
56  	 */
57  	public Class<T> getPersistentClass();
58  	
59  	/**
60  	 * New: this callback is in general no longer required (the constructor
61  	 *  should figure the type out itself).
62  	 *
63  	 * @param c    Mandatory. The domain class this DAO is responsible for.
64  	 */
65  	public void setPersistentClass(Class<T> c);
66  	
67  	/**
68  	 * Re-reads the state of the given domain object from the underlying
69  	 * store.
70  	 *
71  	 * @param entity
72  	 *            The domain object to re-read the state of
73  	 * @throws DataAccessException
74  	 *             If general data access problem occurred
75  	 * @throws DataRetrievalFailureException
76  	 *             If domain object could not be re-read
77  	 * @return The refreshed entity
78  	 */
79  	T refresh(T entity) throws DataAccessException,
80  		DataRetrievalFailureException;
81  	
82  	/**
83  	 * Re-reads the state of the given domain object from the undermost
84  	 * store (eg. the database).
85  	 *
86  	 * @param entity
87  	 *            The domain object to re-load the state of
88  	 * @throws DataAccessException
89  	 *             If general data access problem occurred
90  	 * @throws DataRetrievalFailureException
91  	 *             If domain object could not be re-loaded
92  	 * @return The reloaded entity
93  	 */
94  	T reload(T entity) throws DataAccessException,
95  		DataRetrievalFailureException;
96  
97  	/**
98  	 * Saves or updates the given domain object.
99  	 *
100 	 * @param entity
101 	 *            The domain object to save or update
102 	 * @throws DataAccessException
103 	 *             If general data access problem occurred
104 	 * @throws DataIntegrityViolationException
105 	 *             If domain object could not be inserted due to a data
106 	 *             integrity violation
107 	 * @throws OptimisticLockingFailureException
108 	 *             If domain object has been modified/deleted in the meantime
109 	 * @return The saved or updated domain object
110 	 */
111 	@ReturnsUnchangedParameter
112 	T saveOrUpdate(T entity) throws DataAccessException,
113 		DataIntegrityViolationException, OptimisticLockingFailureException;
114 
115 	/**
116 	 * Deletes the given domain objects. This method executed in a single
117 	 * transaction (by default with the Required semantics).
118 	 *
119 	 * @param entities
120 	 *             The domain objects to delete.
121 	 * @throws DataAccessException
122 	 *             If general data access problem occurred
123 	 * @throws OptimisticLockingFailureException
124 	 *             If domain object has been modified/deleted in the meantime
125 	 */
126 	void delete(Collection<T> entities)
127 		throws OptimisticLockingFailureException, DataAccessException;
128 	
129 	// end GenericDao
130 	// begin ConvenienceGenericDao part
131 	
132 	/**
133 	 * Retrieves a domain object by identifier. This method gets the object from
134 	 * the hibernate cache. It might be that you don't get the actual version
135 	 * that is in the database. If you want the actual version do a refresh()
136 	 * after this method call.
137 	 *
138 	 * @param id
139 	 *            The id of the domain object to find
140 	 * @return Returns the found domain object.
141 	 * @throws DataRetrievalFailureException
142 	 *             If no domain object could be found with given id.
143 	 * @throws DataAccessException
144 	 *             If general data access problem occurred
145 	 */
146 	T findById(ID id) throws DataRetrievalFailureException, DataAccessException;
147 	
148 	/**
149 	 * Deletes the domain object with the given id, disregarding any
150 	 * concurrent modifications that may have occurred.
151 	 *
152 	 * @param id
153 	 *             The id of the domain object to delete
154 	 * @throws OptimisticLockingFailureException
155 	 *             If domain object has been deleted in the meantime
156 	 * @throws DataAccessException
157 	 *             If general data access problem occurred
158 	 */
159 	void deleteById(ID id)
160 		throws OptimisticLockingFailureException, DataAccessException;
161 	
162 	/**
163 	 * Retrieves all the domain objects of type T.
164 	 *
165 	 * @return The list containing all the domain objects of type T; if no such
166 	 *         domain objects exist, an empty list will be returned
167 	 * @throws DataAccessException
168 	 *             If general data access problem occurred
169 	 */
170 	List<T> getAll() throws DataAccessException;
171 	
172 	/**
173 	 * Deletes the given domain object.
174 	 *
175 	 * @param entity
176 	 *             The domain object to delete
177 	 * @throws OptimisticLockingFailureException
178 	 *             If domain object has been modified/deleted in the meantime
179 	 * @throws DataAccessException
180 	 *             If general data access problem occurred
181 	 */
182 	void delete(T entity)
183 		throws OptimisticLockingFailureException, DataAccessException;
184 	
185 	/**
186 	 * Deletes all available <code>T</code>.
187 	 *
188 	 * @throws OptimisticLockingFailureException
189 	 *             If domain object has been modified/deleted in the meantime
190 	 * @throws DataAccessException
191 	 *             If general data access problem occurred
192 	 */
193 	public void deleteAll()
194 		throws OptimisticLockingFailureException, DataAccessException;
195 	
196 	/**
197 	 * Sometimes, the way Hibernate handles all the actions in a session is
198 	 * very unbelievable. For example, we call
199 	 * <code>
200 	 *  delete(project);
201 	 *  project.setId(null) <= to insert new one
202 	 *  insert(project);
203 	 * </code>
204 	 *
205 	 * It could cause java.sql.BatchUpdateException:
206 	 * ORA-00001: unique constraint BECAUSE Hibernate doesn't flush
207 	 * the previous action first.
208 	 *
209 	 * This method provides a way to flush manually some action.
210 	 * Note that this method is only used in an extremely rare case.
211 	 */
212 	void flush();
213 	
214 	// end ConvenienceGenericDao part
215 	
216 	/**
217 	 * Convenience method: Executes saveOrUpdate() and flush() on that entity.
218 	 * 
219 	 * @param entity    The domain object to save or update
220 	 * @return          The saved or updated object
221 	 * @throws DataAccessException
222 	 * @throws DataIntegrityViolationException
223 	 * @throws OptimisticLockingFailureException
224 	 */
225 	@Deprecated
226 	public T saveOrUpdateAndFlush(T entity) throws DataAccessException,
227 		DataIntegrityViolationException, OptimisticLockingFailureException;
228 	
229 	/**
230 	 * merge the given entity.
231 	 * @param entity the entity to merge.
232 	 * @return the merged entity
233 	 * @throws DataAccessException
234 	 * @throws DataIntegrityViolationException
235 	 * @throws OptimisticLockingFailureException
236 	 */
237 	public T merge(T entity) throws DataAccessException,
238 		DataIntegrityViolationException, OptimisticLockingFailureException;
239 	
240 	/**
241 	 * persist the given entity.
242 	 * @param entity the entity to persist.
243 	 * @return the persisted entity
244 	 * @throws DataAccessException
245 	 * @throws DataIntegrityViolationException
246 	 * @throws OptimisticLockingFailureException
247 	 */
248 	public T persist(T entity) throws DataAccessException,
249 		DataIntegrityViolationException, OptimisticLockingFailureException;
250 	
251 	/** 
252 	 * Deletes all available <code>T</code> using a JPQL query.
253 	 * 
254 	 * This has the benefit of a significant performance improvement
255 	 * in comparison to {@link deleteAll}. The tradeoff is that this
256 	 * method does no cascade deletion. 
257 	 *
258 	 * @throws OptimisticLockingFailureException
259 	 *             If domain object has been modified/deleted in the meantime
260 	 * @throws DataAccessException
261 	 *             If general data access problem occurred
262 	 * */
263 //	public void deleteAllNoCascade()
264 //		throws OptimisticLockingFailureException, DataAccessException;
265 	
266 	/**
267 	 * Deletes the given domain objects using a JPQL query. 
268 	 * 
269 	 * This has the benefit of a significant performance improvement
270 	 * in comparison to {@link delete}. The tradeoff is that this
271 	 * method does no cascade deletion. 
272 	 * 
273 	 * @param entities The domain objects to delete.
274 	 * @throws OptimisticLockingFailureException
275 	 *             If domain object has been modified/deleted in the meantime
276 	 * @throws DataAccessException
277 	 *             If general data access problem occurred
278 	 */
279 //	public void deleteNoCascade(Collection<T> entities) throws DataAccessException,
280 //		DataIntegrityViolationException, OptimisticLockingFailureException;
281 
282 	/**
283 	 * Retrieves all the domain objects matching the JPA criteria.
284 	 * 
285 	 * @param criteria             the criteria that the result has to fulfill
286 	 * @return                     all object that fulfill the criteria
287 	 * @throws DataAccessException
288 	 *
289 	 * @see ConvenienceJpaTemplate#findByCriteria(DetachedCriteria)
290 	 */
291 	public List<T> findByQuery(QueryBuilder criteria)
292 		throws DataAccessException;
293 	
294 	/**
295 	 * Retrieves all the domain objects matching the JPA criteria.
296 	 * Loads at least the given extent.
297 	 * 
298 	 * @param criteria             the criteria that the result has to fulfill
299 	 * @param extent               the extent in which objects get loaded.
300 	 * @return                     all object that fulfill the criteria
301 	 * @throws DataAccessException
302 	 *
303 	 * @see ConvenienceJpaTemplate#findByCriteria(DetachedCriteria)
304 	 */
305 	public List<T> findByQuery(QueryBuilder criteria,
306 		DataExtent extent) throws DataAccessException;
307 	
308 	/**
309 	 * Retrieves a range of domain objects matching the JPA criteria.
310 	 * 
311 	 * @param criteria             the criteria that the result has to fulfill
312 	 * @param firstResult          the index of the first result to return
313 	 * @param maxResults           the maximum number of results to return
314 	 * @return                     the specified subset of object that fulfill
315 	 *                             the criteria
316 	 * @throws DataAccessException
317 	 *
318 	 * @see ConvenienceJpaTemplate#findByCriteria(DetachedCriteria, int, int)
319 	 */
320 	public List<T> findByQuery(QueryBuilder criteria,
321 		int firstResult, int maxResults) throws DataAccessException;
322 	
323 	/**
324 	 * Retrieves a range of domain objects matching the JPA criteria.
325 	 * Loads at least the given extent.
326 	 * 
327 	 * @param criteria             the criteria that the result has to fulfill
328 	 * @param firstResult          the index of the first result to return
329 	 * @param maxResults           the maximum number of results to return
330 	 * @param extent               the extent in which objects get loaded.
331 	 * @return                     the specified subset of object that fulfill
332 	 *                             the criteria
333 	 * @throws DataAccessException
334 	 *
335 	 * @see ConvenienceJpaTemplate#findByCriteria(DetachedCriteria, int, int)
336 	 */
337 	public List<T> findByQuery(QueryBuilder criteria, int firstResult,
338 		int maxResults, DataExtent extent) throws DataAccessException;
339 	
340 	/**
341 	 * Retrieves the number of domain objects matching the JPA criteria.
342 	 * 
343 	 * @param criteria             the criteria that the result has to fulfill
344 	 * @return                     the number of objects that fulfill
345 	 *                             the criteria
346 	 * @throws DataAccessException
347 	 *
348 	 * @see ConvenienceJpaTemplate#findCountByCriteria(DetachedCriteria)
349 	 */
350 	public int findCountByQuery(QueryBuilder criteria)
351 		throws DataAccessException;
352 	
353 	/**
354 	 * Retrieves a domain object by identifier. This method gets the object from
355 	 * the hibernate cache. It might be that you don't get the actual version
356 	 * that is in the database. If you want the actual version do a refresh()
357 	 * after this method call.
358 	 * Loads at least the given extent.
359 	 *
360 	 * @param id        The id of the domain object to find
361 	 * @param extent    the extent in which objects get loaded.
362 	 * @return Returns the found domain object.
363 	 * @throws DataRetrievalFailureException
364 	 *             If no domain object could be found with given id.
365 	 * @throws DataAccessException
366 	 *             If general data access problem occurred
367 	 */
368 	public T findById(ID id, DataExtent extent) 
369 		throws DataRetrievalFailureException, DataAccessException;
370 	
371 	/**
372 	 * Retrieves all the domain objects of type T.
373 	 * Loads at least the given extent.
374 	 *
375 	 * @param extent    the extent in which objects get loaded.
376 	 * 
377 	 * @return The list containing all the domain objects of type T; if no such
378 	 *         domain objects exist, an empty list will be returned
379 	 * @throws DataAccessException
380 	 *             If general data access problem occurred
381 	 */
382 	List<T> getAll(DataExtent extent) throws DataAccessException;
383 
384 	/**
385 	 * Re-reads the state of the given domain object from the underlying
386 	 * store.
387 	 * Loads at least the given extent.
388 	 *
389 	 * @param entity
390 	 *            The domain object to re-read the state of
391 	 * @param extent
392 	 *            the extent in which objects get loaded.
393 	 * @throws DataAccessException
394 	 *             If general data access problem occurred
395 	 * @throws DataRetrievalFailureException
396 	 *             If domain object could not be re-read
397 	 * @return The refreshed entity
398 	 */
399 	T refresh(T entity, DataExtent extent) throws DataAccessException,
400 		DataRetrievalFailureException;
401 	
402 	/**
403 	 * Re-reads the state of the given domain object from the undermost
404 	 * store (eg. the database).
405 	 * Loads at least the given extent.
406 	 *
407 	 * @param entity
408 	 *            The domain object to re-read the state of
409 	 * @param extent
410 	 *            the extent in which objects get loaded.
411 	 * @throws DataAccessException
412 	 *             If general data access problem occurred
413 	 * @throws DataRetrievalFailureException
414 	 *             If domain object could not be re-read
415 	 * @return The refreshed entity
416 	 */
417 	T reload(T entity, DataExtent extent) throws DataAccessException,
418 		DataRetrievalFailureException;
419 	
420 }