Улучшенная обработка исключений в JPA

Я использовал EJB3/JPA при сохранении своих объектов, и я доволен тем, как он может управлять моей задачей, связанной с БД. Меня беспокоит только обработка исключений. Мой пример кода при сохранении объекта всегда имеет этот вариант. Большинство учебных пособий, которые я читал в сети, относятся к этому варианту без учета обработки исключений.

@Stateless
public class StudentFacade{
    @PersistenceContext(unitName = "MyDBPU")
    private EntityManager em;

    public void save(Student student) {
        em.persist(student);
    }
}

Но я не знаю, как лучше всего обрабатывать исключения в приложении EJB? Каким должен быть лучший способ обработки исключений?

Это то, как другие обрабатывают исключение? Блок try catch на фасаде вашего сеанса?

@Stateless
public class StudentFacade{
    @PersistenceContext(unitName = "MyDBPU")
    private EntityManager em;

    public void save(Student student) {
        try {
            em.persist(student);
        } catch(Exception e) {
            //log it or do something
        }
    }
}

или позволить методу генерировать исключение?

public void save(Student student) throws Exception {
    em.persist(student);
}

Я не знаю, правильно ли я понимаю, так как я все еще изучаю EJB. Спасибо


person Mark Estrada    schedule 03.10.2011    source источник
comment
если вы выбрасываете исключение, вам не нужно его ловить   -  person Naveen Babu    schedule 03.10.2011


Ответы (3)


Идея обработки исключений заключается в выполнении некоторой логики в одной точке в случае любого сбоя. Уловка try будет использоваться в последней точке, где вам нужно обработать исключение или вам нужно преобразовать исключение в другое исключение.

Скажем, ваше приложение имеет много слоев, а именно Action, Facade, Persist.

Делегировать исключение. В этом случае любое исключение, выброшенное на Facade, может быть выброшено на вышеприведенный уровень действий. В действии конкретное исключение будет перехвачено и обработано с соответствующим сообщением об ошибке.

//This is in Facade Layer
public void save(Student student) throws AppException{
    //exceptions delegated to action layer

    //call to Persist Layer
}

Преобразование общего исключения в исключение приложения. Скажем, в постоянстве вы получаете и DBException, например sqlException. Это исключение не должно быть отправлено как таковое на уровень действия или фасада, поэтому мы перехватываем конкретное исключение, а затем выбрасываем новое исключение (определенное пользователем исключение для приложения).

//This is in Persist Layer
public void save(Student student) throws AppException{
        //converting general exception to AppException and delegating to Facade Layer

        try{
            em.persist(student);//call to DB. This is in Persist Layer
        }catch(Exception e){
            throw new AppException("DB exception", e)
        }
    }

На уровне действия вы поймаете свое исключение в действии, а затем обработаете его там.

  //This is in Action layer
  public void callSave(Student student){
            try{
                //call Facade layer
            }catch(AppException e){
               //Log error and handle
            }
    }
person Naveen Babu    schedule 03.10.2011
comment
Если уровень постоянства является EJB, тогда ваш подход не работает, потому что при фиксации после возврата метода произойдет много исключений. - person Lii; 20.10.2014

Если вы хотите, чтобы ваш метод вызывал исключение, полученное от em.persistance(...), то не окружайте этот оператор этим блоком try/catch (потому что он будет перехватывать каждое исключение, находящееся в этом блоке).

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

В противном случае я бы предложил следовать "эмпирическому правилу" исключений - их следует обрабатывать в первую очередь, когда у вас есть вся необходимая информация о них, чтобы предпринять действия, иначе выбросить их, чтобы кто-то другой мог справиться. (Если вы отбрасываете их, убедитесь, что вы выдали наиболее конкретную форму исключения, которое вы могли бы выдать (не общее исключение)). Обработка исключений при использовании JPA ничем не отличается от обработки исключений Java в целом.

Надеюсь, это была достаточно простая информация об исключениях, не затевающая "религиозный разговор".

person Romeo    schedule 03.10.2011

Если ваша комбинация ejb с jpa, то все исключения jpa являются исключениями во время выполнения.

ejb обрабатывает 2 типа исключений 1) Исключение приложения 2) Исключение системы

Application Exceptions проверенные исключения, в основном, мы используем бизнес-проверку и бизнес-правила.

Системные исключения являются исключениями времени выполнения, поэтому, если какое-либо исключение времени выполнения произойдет, контейнер ejb будет вмешиваться и преобразовывать исключение времени выполнения как удаленное исключение.

Например: в слое дао

public void store(Cargo cargo) {
    entityManager.persist(cargo);
}

Все исключения jpa являются исключениями только во время выполнения.

на сервисном уровне ejb:

public TrackingId bookNewCargo(UnLocode originUnLocode,
        UnLocode destinationUnLocode,
        Date arrivalDeadline) {

    Cargo cargo = new Cargo(trackingId, routeSpecification);
    cargoRepository.store(cargo);
    return cargo.getTrackingId();
}

на уровне ejb, если возникнет какое-либо исключение во время выполнения, контейнер ejb будет мешать и преобразовываться в удаленное исключение.

В интерфейсном слое:

 public String register() {

    try {
         String   trackingId = bookingServiceFacade.bookNewCargo(
                    originUnlocode,
                    destinationUnlocode,
                    arrivalDeadline);


    } catch (Exception e) {
        throw new RuntimeException("Error parsing date", e); 
    }

так что вот так jpa --> ejb --> интерфейс

person rameshvanka    schedule 27.07.2016