2 * Copyright (C) 2001, 2002, 2003, 2004 The Mir-coders group
4 * This file is part of Mir.
6 * Mir is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Mir is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Mir; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * In addition, as a special exception, The Mir-coders gives permission to link
21 * the code of this program with any library licensed under the Apache Software License,
22 * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
23 * (or with modified versions of the above that use the same license as the above),
24 * and distribute linked combinations including the two. You must obey the
25 * GNU General Public License in all respects for all of the code used other than
26 * the above mentioned libraries. If you modify this file, you may extend this
27 * exception to your version of the file, but you are not obligated to do so.
28 * If you do not wish to do so, delete this exception statement from your version.
30 package org.codecoop.mir.core.dao.hibernate;
32 import java.io.Serializable;
33 import java.math.BigDecimal;
34 import java.sql.Timestamp;
35 import java.util.Calendar;
36 import java.util.Date;
37 import java.util.Iterator;
38 import java.util.List;
40 import net.sf.hibernate.Criteria;
41 import net.sf.hibernate.HibernateException;
42 import net.sf.hibernate.Query;
43 import net.sf.hibernate.Session;
44 import net.sf.hibernate.SessionFactory;
45 import net.sf.hibernate.Transaction;
46 import net.sf.hibernate.expression.Criterion;
47 import net.sf.hibernate.expression.Example;
48 import net.sf.hibernate.expression.Expression;
49 import net.sf.hibernate.expression.Order;
51 import org.codecoop.mir.core.dao.DatabaseFailure;
52 import org.codecoop.mir.core.dao.IDAO;
53 import org.codecoop.mir.core.dao.IQueryCriteria;
58 * @version $Id: AbstractDAO.java,v 1.1 2004/11/06 16:20:48 idfx Exp $
60 public abstract class AbstractDAO implements IDAO {
62 private static SessionFactory sessionFactory;
65 * Return the specific Object class that will be used for class-specific
66 * implementation of this DAO.
67 * @return the reference Class
70 protected abstract Class getReferenceClass();
74 * @param query a query expressed in Hibernate's query language
75 * @return a distinct list of instances (or arrays of instances)
77 public List find(String query) throws DatabaseFailure {
78 System.out.println(query);
80 List list = find(query, HibernateSessionManager.getSession());
81 for (Iterator iter = list.iterator(); iter.hasNext();) {
82 initializeCollections(iter.next());
85 } catch (HibernateException e) {
86 throw new DatabaseFailure(e);
90 protected List find(Criteria c) throws DatabaseFailure {
93 returnList = c.list();
94 for (Iterator iter = returnList.iterator(); iter.hasNext();) {
95 initializeCollections(iter.next());
98 } catch (Throwable e) {
99 throw new DatabaseFailure(e);
103 public List find(int limit, int offset) throws DatabaseFailure {
104 return find(limit, offset, null, null);
107 public List find(int limit, int offset, Object example) throws DatabaseFailure {
108 Example ex = Example.create(example);
112 return find(limit, offset, ex, null);
115 protected List find(int limit, int offset, Criterion crit, Order order)
116 throws DatabaseFailure {
118 Session s = HibernateSessionManager.getSession();
119 Criteria c = s.createCriteria(getReferenceClass());
126 c.setFirstResult(offset);
127 c.setMaxResults(limit);
129 } catch (Throwable e) {
130 throw new DatabaseFailure(e);
135 * @see org.codecoop.mir.core.dao.IArticleDAO#findById(java.lang.Integer)
137 protected Object findById(Integer id) throws DatabaseFailure{
139 Session s = HibernateSessionManager.getSession();
140 Criteria c = s.createCriteria(getReferenceClass());
141 c.add(Expression.eq("id", id));
142 return find(c).get(0);
143 } catch (Throwable e) {
144 throw new DatabaseFailure(e);
149 * Perform a find but use the session given instead of creating a new one.
150 * @param query a query expressed in Hibernate's query language
151 * @s the Session to use
153 protected List find(String query, Session s) throws HibernateException {
154 return s.find(query);
158 * Return all objects related to the implementation of this DAO with no filter.
160 public List findAll() throws DatabaseFailure {
162 return findAll(HibernateSessionManager.getSession());
163 } catch (Throwable e) {
164 throw new DatabaseFailure(e);
169 * Return all objects related to the implementation of this DAO with no filter.
170 * Use the session given.
171 * @param s the Session
173 protected List findAll(Session s) throws DatabaseFailure {
175 Criteria crit = s.createCriteria(getReferenceClass());
177 } catch (Throwable e) {
178 throw new DatabaseFailure(e);
184 public List find(IQueryCriteria criteria) throws DatabaseFailure {
185 if(criteria instanceof QueryCriteria){
186 QueryCriteria c = (QueryCriteria)criteria;
187 return find(c.criteria());
189 throw new DatabaseFailure("No applicable implementation of IQueryCriteria");
193 * Obtain an instance of Query for a named query string defined in the mapping file.
194 * @param name the name of a query defined externally
197 protected List getNamedQuery(String name) throws DatabaseFailure {
199 return getNamedQuery(name, HibernateSessionManager.getSession());
200 } catch (Exception e) {
201 throw new DatabaseFailure(e);
206 * Obtain an instance of Query for a named query string defined in the mapping file.
207 * Use the session given.
208 * @param name the name of a query defined externally
209 * @param s the Session
212 protected List getNamedQuery(String name, Session s) throws HibernateException {
213 Query q = s.getNamedQuery(name);
218 * Obtain an instance of Query for a named query string defined in the mapping file.
219 * Use the parameters given.
220 * @param name the name of a query defined externally
221 * @param params the parameter array
224 protected List getNamedQuery(String name, Serializable[] params)
225 throws DatabaseFailure {
227 return getNamedQuery(name, params, HibernateSessionManager.getSession());
228 } catch (Exception e) {
229 throw new DatabaseFailure(e);
234 * Obtain an instance of Query for a named query string defined in the mapping file.
235 * Use the parameters given and the Session given.
236 * @param name the name of a query defined externally
237 * @param params the parameter array
241 protected List getNamedQuery(String name, Serializable[] params, Session s)
242 throws HibernateException {
243 Query q = s.getNamedQuery(name);
244 for (int i = 0; i < params.length; i++) {
245 setParameterValue(q, i, params[i]);
251 * Convenience method to set paramers in the query given based on the actual object type in passed in as the value.
252 * You may need to add more functionaly to this as desired (or not use this at all).
253 * @param query the Query to set
254 * @param position the ordinal position of the current parameter within the query
255 * @param value the object to set as the parameter
257 protected void setParameterValue(Query query, int position, Object value) {
260 } else if (value instanceof Boolean) {
261 query.setBoolean(position, ((Boolean) value).booleanValue());
262 } else if (value instanceof String) {
263 query.setString(position, (String) value);
264 } else if (value instanceof Integer) {
265 query.setInteger(position, ((Integer) value).intValue());
266 } else if (value instanceof Long) {
267 query.setLong(position, ((Long) value).longValue());
268 } else if (value instanceof Float) {
269 query.setFloat(position, ((Float) value).floatValue());
270 } else if (value instanceof Double) {
271 query.setDouble(position, ((Double) value).doubleValue());
272 } else if (value instanceof BigDecimal) {
273 query.setBigDecimal(position, (BigDecimal) value);
274 } else if (value instanceof Byte) {
275 query.setByte(position, ((Byte) value).byteValue());
276 } else if (value instanceof Calendar) {
277 query.setCalendar(position, (Calendar) value);
278 } else if (value instanceof Character) {
279 query.setCharacter(position, ((Character) value).charValue());
280 } else if (value instanceof Timestamp) {
281 query.setTimestamp(position, (Timestamp) value);
282 } else if (value instanceof Date) {
283 query.setDate(position, (Date) value);
284 } else if (value instanceof Short) {
285 query.setShort(position, ((Short) value).shortValue());
290 * Used by the base DAO classes but here for your modification
291 * Load object matching the given key and return it.
293 protected Object load(Class refClass, Serializable key) throws DatabaseFailure {
295 return load(refClass, key, HibernateSessionManager.getSession());
296 } catch (Exception e) {
297 throw new DatabaseFailure(e);
302 * Used by the base DAO classes but here for your modification
303 * Load object matching the given key and return it.
305 protected Object load(Class refClass, Serializable key, Session s)
306 throws DatabaseFailure {
308 return s.load(refClass, key);
309 } catch (HibernateException e) {
310 throw new DatabaseFailure(e);
315 * Used by the base DAO classes but here for your modification
316 * Persist the given transient instance, first assigning a generated identifier.
317 * (Or using the current value of the identifier property if the assigned generator is used.)
319 public Serializable save(Object obj) throws DatabaseFailure {
321 return save(obj, HibernateSessionManager.getSession());
322 } catch (Throwable e) {
323 throw new DatabaseFailure(e);
328 * Used by the base DAO classes but here for your modification
329 * Persist the given transient instance, first assigning a generated identifier.
330 * (Or using the current value of the identifier property if the assigned generator is used.)
332 protected Serializable save(Object obj, Session s) throws HibernateException {
333 Serializable key = null;
334 Transaction transaction = s.beginTransaction();
337 transaction.commit();
338 } catch (HibernateException e) {
339 if(transaction != null){
340 transaction.rollback();
347 * Used by the base DAO classes but here for your modification
348 * Either save() or update() the given instance, depending upon the value of its
349 * identifier property.
351 public void saveOrUpdate(Object obj) throws DatabaseFailure {
352 saveOrUpdate(obj, HibernateSessionManager.getSession());
356 * Used by the base DAO classes but here for your modification
357 * Either save() or update() the given instance, depending upon the value of its
358 * identifier property.
360 protected void saveOrUpdate(Object obj, Session s) throws DatabaseFailure {
363 } catch (Throwable e) {
364 throw new DatabaseFailure(e);
369 * Used by the base DAO classes but here for your modification
370 * Update the persistent state associated with the given identifier. An exception is thrown if there is a persistent
371 * instance with the same identifier in the current session.
372 * @param obj a transient instance containing updated state
375 public void update(Object obj) throws DatabaseFailure {
377 update(obj, HibernateSessionManager.getSession());
378 } catch (Throwable e) {
379 throw new DatabaseFailure(e);
384 * Used by the base DAO classes but here for your modification
385 * Update the persistent state associated with the given identifier. An exception is thrown if there is a persistent
386 * instance with the same identifier in the current session.
387 * @param obj a transient instance containing updated state
388 * @param s the Session
390 protected void update(Object obj, Session s) throws DatabaseFailure {
393 } catch (HibernateException e) {
394 throw new DatabaseFailure(e);
399 * Used by the base DAO classes but here for your modification
400 * Remove a persistent instance from the datastore. The argument may be an instance associated with the receiving
401 * Session or a transient instance with an identifier associated with existing persistent state.
403 public void delete(Object obj) throws DatabaseFailure {
404 delete(obj, HibernateSessionManager.getSession());
408 * Used by the base DAO classes but here for your modification
409 * Remove a persistent instance from the datastore. The argument may be an instance associated with the receiving
410 * Session or a transient instance with an identifier associated with existing persistent state.
412 protected void delete(Object obj, Session s) throws DatabaseFailure {
415 } catch (HibernateException e) {
416 throw new DatabaseFailure(e);
421 * Used by the base DAO classes but here for your modification
422 * Re-read the state of the given instance from the underlying database. It is inadvisable to use this to implement
423 * long-running sessions that span many business tasks. This method is, however, useful in certain special circumstances.
425 protected void refresh(Object obj, Session s) throws DatabaseFailure {
428 } catch (HibernateException e) {
429 throw new DatabaseFailure(e);
433 protected abstract void initializeCollections(Object o) throws DatabaseFailure;