Разъяснение по объявлению бросков

У меня есть следующая транзакция SQL в java

public List<MyObj> find() {
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        List<MyObj> obj = null;
        try {
            tx = session.beginTransaction();
            String sql = " some sql query";
            SQLQuery query = session.createSQLQuery(sql);
            query.addEntity(MyObj.class);
            objs = query.list();
            tx.commit();
        }
        catch(Exception e) {
            if (tx != null) tx.rollback();

        }
        finally {
            session.close();
        }
        return objs;

    }

Должен ли я ловить SQLException вместо Exception? Когда я меняю класс на SQL Exception, я получаю сообщение об ошибке, что я должен добавить предложение throws, а затем удалить предложение catch.

Могу ли я добавить объявление throws и по-прежнему перехватывать и обрабатывать SQLException? в этом случае откат?


person user_mda    schedule 27.03.2017    source источник
comment
Какова точная ошибка компилятора?   -  person developer    schedule 27.03.2017
comment
Недостижимый блок catch для SQLException. Это исключение никогда не выбрасывается из тела оператора try.   -  person user_mda    schedule 27.03.2017
comment
Hibernate оборачивает исключения в HibernateException, так что вы можете просто поймать это. RuntimeException тоже будет работать, но тогда вы поймаете больше, чем просто HibernateException. Лучше быть конкретным.   -  person Joe.b    schedule 27.03.2017
comment
catch(Exception ...) является антипаттерном, как и throws Exception. Всегда имейте дело с более конкретными исключениями.   -  person Lew Bloch    schedule 27.03.2017


Ответы (1)


Hibernate API не выдает SQLException (который является проверенным Exception), поэтому вы не можете его поймать.

Хорошей практикой является catch RuntimeException (для обработки исключений, возникших из-за проблем с кодом, таких как нулевые ссылки и т. д. или исключения, выдаваемые Hibernate API) и rollback транзакции, вы можете посмотреть документацию по Hibernate здесь примеры отката транзакций.

try {
        tx = session.beginTransaction();
        String sql = " some sql query";
        SQLQuery query = session.createSQLQuery(sql);
        query.addEntity(MyObj.class);
        objs = query.list();
        tx.commit();
    }
    catch(RuntimeException e) {
        if (tx != null) tx.rollback();
         throw e;
    }
    finally {
        session.close();
    }

Я думаю, что ошибка означает, что я должен сначала объявить предложение throws, указывающее, что блок кода выдаст правильное SQLEXception?

Нет, поскольку Hibernate уже оборачивает проверенный SQLException в один из непроверенных объектов Exception (список приведен ниже), вам не нужно ни catch этого исключения, ни throws в подписи метода.

Я настоятельно рекомендую вам прочитать эту ссылку о том, почему фреймворки Hibernate или Spring вышли из проверенных исключения (например, SQLException и т. д.).

Есть ли документ, в котором говорится, что SQLexception не вызывается API-интерфейсом гибернации?

Вы можете посмотреть здесь для списка исключений Hibernate.

person developer    schedule 27.03.2017
comment
Я думаю, что ошибка означает, что я должен сначала объявить предложение throws, указывающее, что блок кода выдаст правильное SQLEXception? Есть ли документ, в котором говорится, что SQLexception не вызывается API-интерфейсом гибернации? - person user_mda; 27.03.2017
comment
Обновил ответ, посмотри - person developer; 27.03.2017
comment
@user_mda Есть ли документ, в котором говорится, что SQLException не вызывается API гибернации [sic]? Да, Hibernate Javadocs. Вы смотрели в них? - person Lew Bloch; 27.03.2017