- This topic has 3 replies, 3 voices, and was last updated 17 years, 11 months ago by bsavardnok.
-
AuthorPosts
-
Steve PriorMemberPretty recently I was adding another POJO object to a fairly large project which uses Hibernate and I started to wish for an alternative to having a DAO class for every POJO object even though some of them had no special methods. After playing around for a bit I came up with a GenericDAO which uses JDK 1.5 generics and have been very happy with it ever since and thought I’d share it. Using it in that project I mentioned reduced my DAO code from about 4000 lines down to 1000 lines with no loss in functionality.
The full code for GenericDAO (I didn’t care for all the logging anyway) is:
package com.geekster; import java.io.Serializable; import java.util.List; import org.hibernate.LockMode; import org.hibernate.criterion.Example; public class GenericDAO<POJO> extends BaseHibernateDAO { public void save(POJO transientInstance) { try { getSession().saveOrUpdate(transientInstance); } catch (RuntimeException re) { throw re; } } public void delete(POJO persistentInstance) { try { getSession().delete(persistentInstance); } catch (RuntimeException re) { throw re; } } @SuppressWarnings("unchecked") public POJO findById( Class c, Serializable id) { try { POJO instance = (POJO) getSession().get(c, id); return instance; } catch (RuntimeException re) { throw re; } } public List findByExample(POJO instance) { try { List results = getSession() .createCriteria(instance.getClass()) .add(Example.create(instance)) .list(); return results; } catch (RuntimeException re) { throw re; } } @SuppressWarnings("unchecked") public POJO findOneExample(POJO instance) { try { POJO result = (POJO)getSession() .createCriteria(instance.getClass()) .add(Example.create(instance)) .uniqueResult(); return result; } catch (RuntimeException re) { throw re; } } @SuppressWarnings("unchecked") public POJO merge(POJO detachedInstance) { try { POJO result = (POJO) getSession() .merge(detachedInstance); return result; } catch (RuntimeException re) { throw re; } } public void attachDirty(POJO instance) { try { getSession().saveOrUpdate(instance); } catch (RuntimeException re) { throw re; } } public void attachClean(POJO instance) { try { getSession().lock(instance, LockMode.NONE); } catch (RuntimeException re) { throw re; } } }
Now the interesting trick is that if you need to add some custom DAO code, you can extend the GenericDAO with a filled in class, for example:
public class BookmarkDAO extends GenericDAO<Bookmark> { public String someCustomDAOMethod(){ // do something return "hi there"; } }
The only concession I had to make was to pass the class object to the findById method, here are some examples of the GenericDAO in use:
GenericDAO<Bookmark> bookmarkDAO = new GenericDAO<Bookmark>(); Bookmark bookmark = bookmarkDAO.findById(Bookmark.class, 1); Bookmark example = new Bookmark(); List<Bookmark> bookmarks = bookmarkDAO.findByExample(example);
I thought others might find this useful. If you do nothing but basic CRUD there is no need to for a DAO class for every POJO, but it is easy to add function if you want to by extending the GenericDAO class.
Enjoy
Steve
Brian FernandesModeratorSteve,
Thanks for sharing this with everyone. We do not generate a single DAO class because we’re still sticking to code which works in both 1.4 and 1.5 and we also generate a few methods that are specific to each DAO.
But we’re always looking at improving some of our generated code and perhaps adding 1.5 support as well;we’ll take a close look at your pattern here.Thanks,
Brian.
Steve PriorMemberYeah, I know this isn’t for everyone because of the JDK 1.5 issue and for that reason wasn’t trying to suggest changing to it in the code generator, but folks who like it can just copy it into their projects. I like it more and more as time goes on.
bsavardnokMembersprior,
I like it.
Thanks for taking the time to contribute. -
AuthorPosts