Лучший способ справиться с нарушениями ограничений при использовании EJB 3.0 и CMP - PullRequest
1 голос
/ 03 ноября 2011

У меня есть веб-сервис (созданный с использованием jaxb / jaxws), который вызывает EJB без сохранения состояния для хранения некоторых данных в базе данных.Данные хранятся как объектный компонент.Компонент-сущность имеет уникальное ограничение, примененное к нему посредством аннотации @Column(unique = true).

Когда веб-служба пытается сохранить данные, транзакция завершается неудачно, и это справедливо.Проблема заключается в том, что, поскольку я использую CMP, транзакция не фиксируется до тех пор, пока не будет выполнен вызов EJB без сохранения состояния.Конечный результат заключается в том, что я не могу перехватить исключение, и оно направляется в стек WS, что приводит к неоднозначной ошибке, содержащей строку: Error committing transaction:;nested exception is: weblogic.transaction.internal.AppSetRollbackOnlyException.

Есть ли способ перехватитьисключение выдается, чтобы я мог предоставить звонящему больше информации?Спасибо.

Информация о версии:

  • Сервер приложений: Oracle Weblogic 10.3
  • Поставщик постоянства: Hibernate 3.2.5.ga (JPA 1.0)
  • JDK / JRE: 1.6_0_05 (предоставляется установкой Weblogic)

Обновление: я попытался внедрить перехватчик EJB 3 вокруг вызова метода, но это не работает.

public class TestInterceptor {

@AroundInvoke
public Object logCall(InvocationContext context) throws Exception {

    System.out.println("Invoking method: " + context.getMethod().getName());

    try {
        return context.proceed();
    } catch (Throwable t) {
        System.out.println("I caught an exception: " + t.getMessage());
        throw new Exception(t);
    }

}

Причина, по которой я думаю, что это не работает, заключается в том, что цепочка обработки такова, что фактическое постоянство происходит вне метода (конечно).

1 Ответ

2 голосов
/ 03 ноября 2011

Вы можете попробовать использовать Bean Validation . Он хорошо связан с JPA (вызывается на этапах pre-persist, pre-update и pre-remove) и может использоваться на разных уровнях вашего приложения.

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

РЕДАКТИРОВАТЬ: Я не уверен, была ли доступна проверка бина в Java EE 5.

РЕДАКТИРОВАНИЕ 2: Вы можете создать перехватчик, который будет перехватывать исключение, выданное JPA (или, точнее, базой данных). Поскольку перехватчик вызывается как часть той же транзакции, что и метод EJB, вам может потребоваться явный вызов EntityManager # flush (-) для синхронизации изменений с базой данных.

...