Tuesday, March 4, 2008

saveOrUpdateOrMerge method for Hibernate

Problem
Due to a very non-normalised proprietary database scheme, when doing an update() with Hibernate through Spring's HibernateTemplate, the system sometimes throws NonUniqueObjectExceptions, which can be avoided by doing a merge().

Solution
I added the following convenience method in my AbstractDao class and use this one instead of the Template's update or merge methods. It isn't perfect, but does its job :-)

public void saveOrUpdateOrMerge(Object obj) throws CareDaoException {
try {
getHibernateTemplate().update(obj);
getHibernateTemplate().flush();
}
catch(HibernateSystemException e) {
if (e.getCause() instanceof NonUniqueObjectException) {
logger.warn("update: NonUniqueObjectException found: retrying with merge()");
getHibernateTemplate().merge(obj);
}
else
throw e;
}
}

The flush is needed to send the query to the db straight away, if not, it would do this only at commit time (on a higher level) and the exception wouldn't be caught in the Dao class.

No comments: