Лучшая обработка исключений в 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. Спасибо
3 ответа:
Идея обработки исключений заключается в выполнении некоторой логики в одной точке в случае любого сбоя. Try catch будет использоваться в конечной точке, где вам нужно обработать исключение или преобразовать исключение в другое исключение
Предположим, что ваше приложение имеет много слоев, а именно Action, Facade, Persist
Исключение делегата В этом случае любое исключение, которое выбрасывается на фасаде, может быть выброшено на указанный выше слой действия. В действии конкретное исключение будет поймано и обработано с правильным сообщением об ошибке.
//This is in Facade Layer public void save(Student student) throws AppException{ //exceptions delegated to action layer //call to Persist Layer }
Преобразование общего исключения в исключение приложения Скажем, в persistence вы получаете и 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 } }
Если вы хотите, чтобы ваш метод выбросил исключение, полученное от em.настойчивость(...), то не окружайте это утверждение блоком try / catch (потому что он будет ловить каждое исключение, которое находится в этом блоке).
То, как вы подходите к этой проблеме, зависит от приложения, существует ли уже какой-то устаревший код или нет. В случае с устаревшим кодом я предлагаю вам использовать тот же подход (даже в некоторых случаях это не оптимальная скорость) для поддержания согласованности.
В противном случае Я бы предложил следовать "эмпирическому правилу" исключений - они должны рассматриваться в первую очередь там, где у вас есть вся необходимая информация о них, чтобы предпринять действие, иначе бросьте их, чтобы кто-то другой мог справиться. (Если вы отбрасываете их, убедитесь, что вы отбрасываете наиболее конкретную форму исключения, которую вы могли бы отбросить (не общее исключение)). Обработка исключений при использовании JPA ничем не отличается от обработки исключений Java в целом.
Я надеюсь, что это была достаточно простая информация о исключения без начала "религиозного разговора".
Если ваша комбинация ejb с jpa, то все исключения jpa являются исключениями времени выполнения.
Ejb обработка 2 типов исключений 1) исключение Приложения 2) исключение системы
Исключения приложений проверенные исключения в основном мы используем бизнес-валидацию и бизнес-правила.
Системные исключения являются исключениями среды выполнения, так что если произойдет какое-либо исключение среды выполнения, контейнер ejb вмешается и преобразует исключение среды выполнения в удаленное исключение.
Для ex: в слой Дао
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 -- > интерфейс