Лучшая обработка исключений в JPA - PullRequest
16 голосов
/ 03 октября 2011

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

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

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

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

Это то, как другие обрабатывают исключение?Попробовать блок 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.Спасибо

Ответы [ 3 ]

12 голосов
/ 03 октября 2011

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

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

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

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

    //call to Persist Layer
}

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

//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)
        }
    }

В действии Layer Вы поймаете свое исключение в действии, а затем обработаете исключение там

  //This is in Action layer
  public void callSave(Student student){
            try{
                //call Facade layer
            }catch(AppException e){
               //Log error and handle
            }
    }
3 голосов
/ 03 октября 2011

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

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

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

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

0 голосов
/ 27 июля 2016

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

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

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

Системные исключения являются исключениями времени выполнения, поэтому при возникновении каких-либо исключений во время выполнения контейнер 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 -> interface

...