2009-10-03 3 views
4

Я использую EJB3 на Glassfish, используя диспетчер устойчивости TopLink по умолчанию. Внутри Session Bean, когда менеджер сохранения выполняет исключение БД, он отмечает отмененную транзакцию и генерирует исключение EJBException, в свою очередь, обертывание исключения RollbackException. Теперь я ожидал получить исходное исключение jdbc из вызванного исключением из одного из этих исключений, но это не так.EJB3 Знакомство с оригинальными ошибками JDBC

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

Кто-нибудь знает, можно ли получить эту информацию от Toplink? Или возможно ли Hibernate?

Спасибо,

ответ

1

Единственный способ, которым я нашел то, что хочу, - заставить менеджера писать в db с помощью manager.flush(), а затем поймать PersistenceException, которое это выбрасывает. Затем я могу зарегистрировать ошибку базы данных, как я хочу, и выбросить исключение EJBException для принудительного отката. Оставляя контейнер, чтобы сделать флеш, кажется, безвозвратно теряют любые полезные сообщения с TopLink.

+1

У меня такая же проблема, можете ли вы отредактировать свой ответ с помощью образца кода? –

1

Хороший вопрос, Ant

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

  • Сбой подключения к базе данных
  • запрос неправильно
  • таблицы или столбца не существует

Выше вы видите приложение не сможет восстановить свое первоначальное состояние , Если вы считаете возможным восстановить его начальное состояние , вы должны использовать исключение приложения. Клиент получит ту же самую исключение для приложения, созданное вашим бизнес-методом. Если вы хотите, чтобы иметь возможность получить точное исключение брошенного вашего метода бизнеса у вас есть два варианта:

  • Использование бизнеса-делегат шаблон для доступа к вашей EJB

Как вы знаете, завернутое исключения во время выполнения по EJBException, так что вы shold использовать что-то вроде

Давайте предположим, что у вас есть этот сессионный компонент

@Stateless 
public class BeanImpl implements Bean { 

    public void doSomething() { 

     try { 
      // some code 
     } catch(SomeException e) { 
      throw new EJBException(e); 
     } 

    }   

} 

так у НУ обернуть сессионный компонент через бизнес-делегат

public class BeamBusinessDelegate implements Bean { 

    // your stateless session bean goes here 
    private Bean bean; 

    public BeamImpl() { 
     InitialContext i = new InitialContext(); 

     bean = (Bean) i.lookup(<GLOBAL_JNDI_ADDRESS_OR_RELATIVE_ENVIRONMENT_NAMING_CONTEXT_ADDRESS>); 
    } 

    public void doSomething() { 
     try { 
      bean.doSomething() 
     } catch(EJBException e) { 
      throw e.getCause(); 
     } 
    } 
} 

Или вы можете расширяет EJBException в соответствии с вашими потребностями

public class DatabaseException extends EJBException { 

} 

Так что в вашем методе бизнес

@Stateless 
public class BeanImpl implements Bean { 

    public void doSomething() { 

     try { 
      // some code 
     } catch(SomeException e) { 
      throw new DatabaseException(); 
     } 

    }   

} 

приветом,

+0

Привет - спасибо за ответ. Ваши примеры демонстрируют в точности то, что мы уже делаем. Я думаю, вы неправильно поняли мою проблему. Проблема заключается в том, что Toplink, Glassfishes по умолчанию, менеджер констант, не включает исходную причину в поле причины в EJBException. Итак, мой вопрос в том, есть ли способ заставить Toplink правильно включить причину, или Hibernate делает это лучше? –

+0

Ой - и похоже, что не было ясно, что это не мой код, который бросает исключение - мы используем Entity Beans для сохранения данных, и это менеджер персистентности, бросающий EJBException, который обертывает исключение RolledbackException, которое делает не имеет своей причины. –

+0

Ant, JPA - абстракция более высокого уровня над JDBC. Я думаю, что вы не можете получить доступ к базовому слою JBDC. После просмотра PersistenceException - http://www.oracle.com/technology/products/ias/toplink/jpa/resources/javadoc/javax/persistence/PersistenceException.html - корневое исключение Java Persisntece API, оно не предоставляет вам способ в котором вы можете получить доступ к базовому уровню JDBC, поэтому я думаю, что это невозможно. –

3

Я была такая же проблема. Я закончил использование метода перехватчика AroundInvoke, таким образом вы можете поймать любое исключение на стороне сервера и извлечь всю информацию, которую хотите, и обернуть ее, чтобы выбросить свое собственное исключение, и установите EjbContext для отката транзакции.

Я могу предоставить вам пример, если вы не придете.

+1

Я раньше не сталкивался с перехватчиками, но только что прочитал их, и это похоже на то, что я хочу. Однако похоже, что я могу определить Interceptors для бизнес-методов и для событий жизненного цикла, но ни один из них, похоже, не совсем то, что я хочу, поскольку методы, которые я хочу перехватить, находятся в EntityManager. Еще несколько указателей были бы с благодарностью приняты! –

1

У меня такой же вопрос: как получить сообщение об ошибке SQL, сгенерированное из JPA?

Я не нашел решение либо, но я добавил эту строку в моей persistence.xml

<properties> 
     <property name="toplink.logging.level" value="FINE" /> 
    </properties> 

и теперь я могу видеть команды SQL выданные.

Ссылка: http://www.jairrillo.com/blog/2008/09/04/introduction-to-jpa-part-1-getting-started/

 Смежные вопросы

  • Нет связанных вопросов^_^