Нужно ли заключать все методы saveOrUpdate в try-catch? - PullRequest
0 голосов
/ 22 июня 2011

Всегда ли мне нужно заключить saveOrUpdate или delete в Session в DAO с блоком try-catch, подобным этому ниже?

public void save(Inventory object) {
    try {
        factory.getCurrentSession().saveOrUpdate(object);
    } catch (Exception e) {
        _logger.error("Cannot save or update object " + object, e);
    }
}

Ответы [ 4 ]

2 голосов
/ 22 июня 2011

Как правило, это зависит от того, хотите ли вы обрабатывать определенные исключения в вашем DAO или нет. Но обратите внимание, что в вашем конкретном примере сеанс может не сбрасываться, и в результате вы все равно не получите никаких интересных исключений (например, нарушение ограничений). Так что я бы сказал, что имеет меньше смысла ловить их, чем позволять им размножаться. Но нет твердого правила.

1 голос
/ 22 июня 2011

org.hibernate.Session.saveOrUpdate выдает HibernateException, так что да, вероятно, это хорошая идея, чтобы перехватить исключение. Но я бы порекомендовал сделать всю транзакцию в блоке try / catch, если вы можете, чтобы откатить ее в случае сбоя. Вот общая идиома для этого:

 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();
 }

Вы можете найти более подробную информацию здесь и, в более общем смысле, о спящем режиме здесь .

0 голосов
/ 22 июня 2011

Наша задача - позволить коду бизнес-логики, который обрабатывает, делать попытку и ловить исключение, потому что он будет знать, нужно ли повторять попытку или нет, и что делать дальше. Класс DAO будет перехватывать все исключения и генерировать код бизнес-логики, тем самым концентрируясь только на неработающей части базы данных. Таким образом, классы DAO всегда можно будет использовать повторно в будущем.

0 голосов
/ 22 июня 2011

Есть несколько шаблонов, которые вы можете использовать.

Самое простое - просто объявить throws Exception, но бросание Exception - очень плохой выбор дизайна - это слишком высокий уровень. Фактически, Villan - это Hibernate - его методы должны быть объявлены как бросающие что-то более узкое, чем Exception.

Лучший способ:

  1. определяет «исключение домена», например, MyDatabaseException
  2. объявите ваш метод, чтобы бросить это
  3. перехватить, а затем повторно выдать исключение, заключенное в исключение вашего домена

Как это:

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

Этот второй подход является часто используемым шаблоном.

P.S. Если вы объедините это с хорошей идеей @ Seth о try-catch-finally, вы получите еще лучший подход.

...