Данные не сохраняются при использовании HIbernate с аннотацией @Transactional в Spring - PullRequest
1 голос
/ 02 февраля 2010

У меня есть приложение, которое я сейчас пишу, которое будет использовать Spring и Hibernate. На своем уровне услуг я ввел DAO, который будет выполнять некоторые базовые действия по CRUD-обработке. Для ухмылки я создал метод, аннотированный следующим образом:

@Transactional(readOnly = false, propogation=Propogation.REQUIRES_NEW)
public void doSomeWork(Dao dao, Entity e){
    //do some searching
    dao.persist(e);
    dao.findAll(Entity.clz);
}

Метод dao persist выглядит следующим образом:

public void persist(Entity e){
     session.saveOrUpdate(e); //This has already been built using a SessionFactory
}

Метод dao findAll выглядит следующим образом

public void findAll(Class clz) {
     session.createCriteria(clz).list();
}

Теперь, кажется, все работает, хорошо. После того, как я вставил (сохранил) свой объект, я могу увидеть его с помощью метода findAll (вместе с новым идентификатором первичного ключа, который был назначен хранилищем данных), однако, когда метод doSomeWork завершается, мои данные фактически не сохраняются в базовом хранилище данных (Oracle 10g).

Однако, если я удаляю аннотации @Transactional и использую Hibernate для session.getTransaction (). Begin () и session.getTransaction (). Commit () (или отката), код работает так, как я ожидал.

Итак, мой основной вопрос был бы: не использует ли Hibernate управление транзакциями в Spring для фактического управления транзакциями?

В моем файле конфигурации bean-компонента я объявляю bean-компонент TransactionManager, компонент SessionFactory и также включаю его в файл конфигурации.

Чего мне, возможно, не хватало, кроме лучшего знания о Spring и Hibernate?

Ответы [ 4 ]

4 голосов
/ 02 февраля 2010

Не забудьте добавить <tx:annotation-driven> для @Transactional поддержки

2 голосов
/ 02 февраля 2010

звучит так, будто весна на самом деле не вводит код обработки транзакции.у вас есть что-то подобное в вашем конфигурационном файле, чтобы сказать Spring, где искать аннотированные классы?

1 голос
/ 02 февраля 2010

Хорошо, спасибо всем, кто откликнулся ... это помогло мне понять, что я делаю не так ...

В моем слишком усердном «доказательстве концепции» меня никогда не замечало, что происходит, пока я не осознал, что мой «простой java-класс с основным методом, который будет выполнять всю мою работу» не управляется весной , следовательно, нет реального управления транзакциями. Это никоим образом не будет вести себя так, как приложение продукта, управляемое сервером приложений с компонентами контроллера, службами и т. Д.

Потом меня осенило ... "услуги" ... У меня будет слой служб, где будет жить поддержка транзакций. Итак, прямо как дождь, я создал простой служебный бин (помеченный @Transactional), и он работает так, как я надеюсь. Итак, я вызываю методы на своем сервисе, который вызывает методы на моем Dao и bam !!! оно работает.

Еще раз спасибо всем, кто помог мне прийти к такому выводу.

1 голос
/ 02 февраля 2010

Какой метод вы используете для получения объекта сеанса из фабрики сеансов? Вы используете openSession(), или getCurrentSession(), или, возможно, что-то еще? Это важно, потому что вам нужно сессию для привязки к весенней транзакции (сомневаюсь, что openSession подходит для вашего сценария)

Я предлагаю вам использовать hibernateTemplate Spring для вызова saveOrUpdate и сохранения, вместо использования объекта сеанса. Таким образом вы гарантируете, что он будет связан с транзакцией, и, как обещает Spring, вам не нужно будет менять код, если вы когда-либо измените стратегию управления транзакциями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...