0

Do I always need to enclose the saveOrUpdate or delete on Session in DAOs with try-catch block like this bellow?

public void save(Inventory object) {
    try {
        factory.getCurrentSession().saveOrUpdate(object);
    } catch (Exception e) {
        _logger.error("Cannot save or update object " + object, e);
    }
}
Rihards
  • 10,241
  • 14
  • 58
  • 78

4 Answers4

2

Generally it depends on whether you want to handle specific exception in your DAO or not. But note, that in your specific example, session may not be flushed and as a result you will not get any interesting exceptions (like constraint violation) anyway. So I'd say it makes less sense to catch them than to allow them to propagate. But there is no firm rule.

Alex Gitelman
  • 24,429
  • 7
  • 52
  • 49
  • As Alex says. You need to make sure the session is committed or rolled back and usually closed as well somewhere. Where depends on what you want. – MJB Jun 22 '11 at 01:26
1

org.hibernate.Session.saveOrUpdate throws HibernateException, so yes, it's probably a good idea to catch the exception. But I'd recommend doing your entire transaction in a try/catch block if you can so that you can roll it back if it fails. Here's a common idiom for doing this:

 Session sess = factory.openSession();
 Transaction tx;
 try {
     tx = sess.beginTransaction();
     //do some work
     //(your call to saveOrUpdate() would go in here somewhere)
     ...
     tx.commit();
 }
 catch (Exception e) {
     if (tx!=null) tx.rollback();
     throw e;
 }
 finally {
     sess.close();
 }

You can find more information here and more generally about hibernate here.

Seth
  • 5,596
  • 8
  • 42
  • 56
0

There are a couple of patterns you could use.

The simplest is to just declare throws Exception, but throwing Exception is a very poor design choice - it's way too high-level. In fact, the villan is Hibernate - its methods should be declared as throwing something more narrow than Exception.

A better way is to:

  1. define a "domain exception", eg MyDatabaseException
  2. declare your method to throw that
  3. catch then re-throw the exception wrapped in your domain exception

Like this:

public void save(Inventory object) throws MyDatabaseException {
    try {
        factory.getCurrentSession().saveOrUpdate(object);
    } catch (Exception e) {
        throw new MyDatabaseException(e);
    }
}

This second approach is a commonly used pattern.

P.S. If you combine this with @Seth's good idea of try-catch-finally, you'd get an even better approach.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
0

Our design is to let the business logic code that handle do the try and catch exception because it would know if it need to retry or not and what to do next. The DAO class will catch all exception and throw to the business logic code thereby only concentrate on database crud part. So the DAO classes will always be reusable in the future.

Jasonw
  • 5,054
  • 7
  • 43
  • 48