2014-09-09 3 views
2

у меня есть EJB проект со следующими модулями:Передача @ApplicationException через несколько модулей EJB

  • модуль отдыха, который обрабатывает вызовы API
  • модуль API, который предоставляет интерфейс для ядра
  • основной модуль, который содержит фактическую бизнес-логику

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

@ApplicationException(rollback = true) 
public class InvalidParameterException extends WebApplicationException { } 

Эти исключения никогда не должны быть уловлены. При аннотации к нему как ApplicationException он не попадает в журнал журнала Glassfish. Пока все работает нормально.

Теперь у меня есть ситуация, когда основной модуль включает в себя другой модуль EJB, который включает в себя его собственные подклассы WebApplicationExceptions, которые выглядят похожими на вышеупомянутые. Это исключение передается в ядро, как должно. Однако, когда это исключение передается остальному модулю, оно обернуто в javax.ejb.EJBTransactionRolledbackException, что заставляет журнал сервера Glassfish регистрировать все эти исключения, чего я бы хотел избежать.

Итак, аннотация @ApplicationException работает только тогда, когда исключение передается от модуля ejb к основному модулю, однако, как только он передается дополнительному модулю, аннотация перестает действовать.

Есть ли хороший способ передать исключение как исключение приложения через несколько модулей? Я знаю, что я мог поймать Exception и снова восстановить его как ApplicationException, однако это сильно раздует код и не будет очень хорошим решением. Есть ли способ лучше?

Edit: Некоторые примеры кода модуля

отдых:

@Path("/someservice") 
@Stateless 
public class SomeResource { 

    @EJB private SomeService someService; 

    @GET 
    @Produces("application/json") 
    public Response someGetMethod() { 
     this.someService.someMethod(); 
     return Response.ok().build(); 
    } 
} 

апи модуль:

public Interface SomeService { 
    public void someMethod(); 
} 

модуль ядра:

@Stateless 
public Class SomeServiceImpl implements SomeService { 

    @EJB private ExternalEJB externalEJB; 

    public void someMethod() { 
     externalEJB.externalMethod(); 
    } 
} 

Внешний модуль EJB. В pom.xml (модуль ядра) с помощью <type>ejb</type>

@Stateless 
public class ExternalEJB { 
    public void externalMethod() { 
     throw new ExternalApplicationException(); 
    } 
} 

Исключения из внешнего модуля:

@ApplicationException 
public class ExternalApplicationException extends WebApplicationException { 

    private static final long serialVersionUID = 1L; 

    public ExternalApplicationException() { 
     super(Response.serverError().build()); 
    } 
} 
+0

Мы часто используем '@ ApplicationException', и они корректно всплывают через множественные вызовы EJB как исключенные. Тем не менее, я вижу, что ваше аннотирование имеет «rollback = true» - не значит ли это 'EJBTransactionRolledBackException' именно то, что вы хотели? –

+0

Это потому, что модуль отдыха находится вне контейнера EJB.Вообще говоря, и, к сожалению, вы не можете беспрепятственно подключать вызовы EJB и REST без обработки подклассов EJBException, которые REST-модуль (как клиент EJB) обречен обрабатывать, когда дело касается транзакций и безопасности. – Osw

+0

@AlexanderLanger Я только что проверил это. Если я удалю «rollback = true» (по умолчанию - false), поведение немного не изменится. –

ответ

0

Измените бизнес-исключения для расширения EJBException и захвата в REST слое как:

try { 
    // my code 
} 
catch (MyCustomExceptionThatExtendsEJBException e) { 
    // catch my exceptions. 
} 
Смежные вопросы