Скажем, у меня есть следующий общий dao, развернутый как локальный SLSB:
public interface CrudService {
public <T> T create(T t);
public <T> T find(Object id, Class<T> type);
public <T> T update(T t);
public void delete(Object t);
public List<Object> findByNamedQuery(String queryName);
public List<Object> findByNamedQuery(String queryName, int resultLimit);
public List<Object> findByNamedQuery(String namedQueryName, Map<String, Object> parameters);
public List<Object> findByNamedQuery(String namedQueryName, Map<String, Object> parameters, int resultLimit);
}
Этот DAO используется во многих других сервисах SLSB.Я хотел бы абстрагировать весь слой постоянства (все операции и исключения) от бизнес-логики.Я создал перехватчик с помощью метода @AroundInvoke, как показано ниже, и поместил его на уровень класса DAO:
@AroundInvoke
public Object wrapExceptions(InvocationContext context) throws Exception {
try {
return context.proceed();
} catch(Exception e) {
throw mapToApplicationException(e)
}
}
Никаких исключений не было получено, и поэтому он отображен с реализациями по умолчанию методов dao.Но если я использую flush в конце методов persist, update и delete, это работает - и это нормально.
Теперь мой вопрос: это единственный способ заставить его работать?Я знаю, что колл-флеш довольно тяжелый, и если мне понадобится колл, скажем, обновить несколько раз, это будет серьезным узким местом.
Редактировать: другой вариант - использовать BMT, но он вызывает загрязнение всех методов фасада с помощью tx.begin () и т.д ...
РЕДАКТИРОВАТЬ после ответа Криса Бабича:
У меня есть некоторые сомнения по предложению Криса.Работа с PersisteceException в сервисном слое вызывает смешивание прозрачности слоев.Но это не самое страшное для меня.Скажите, что у меня есть Service Facade, использующий набор моих услуг или DAO.Метод Service Facade должен быть выполнен в его собственной транзакции, поэтому я бы использовал CMT и пометил его @TransactionAttribute (REQUIRES_NEW).В этом случае нет места для точки обработки исключений (перехватчик не будет работать, потому что транзакция все еще продолжается - это тот же случай, что и выше).Поэтому я вижу два пути: либо использовать все методы фасадов, использующие BMT, и обрабатывать все вещи tx.begin (), tx.commit () и т. Д., Либо использовать другой «Фасад для фасада» с @TransactionAttribute (NEVER), а затем вызватьТранзакционный фасад и обработка его исключений.