EJB3 Начало оригинальных ошибок JDBC - PullRequest
4 голосов
/ 03 октября 2009

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

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

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

Спасибо

Ответы [ 4 ]

3 голосов
/ 05 октября 2009

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

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

1 голос
/ 27 октября 2009

У меня тот же вопрос: как получить сообщение об ошибке 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/

1 голос
/ 13 октября 2009

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

1 голос
/ 03 октября 2009

Хороший вопрос, Муравей

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

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

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

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

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

Предположим, у вас есть сессионный компонент без сохранения состояния

@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();
        }

    }        

}

С уважением,

...