У меня есть приложение JSF2, использующее JPA2/Hibernate с Spring @Transactional. В пользовательском интерфейсе нет операторов @Transactional (бэк-бины), только на уровне сервиса. (Я использую @Transactional(propagation=Propagation.MANDATORY) в DAO, чтобы убедиться, что каждый вызов происходит в транзакции.) Все работает очень хорошо, за исключением...
Когда я открываю и обновляю объекты с помощью методов транзакционной службы, иногда полученные объекты устаревают. Неважно, что это один и тот же пользователь в том же сеансе, иногда методы «чтения» JPA возвращают старые устаревшие объекты, которые (должны были) уже быть заменены. Это поставило меня в тупик на некоторое время, но оказалось, что это вызвано кэшированием в Entity Manager. DAO аннотируются @Repository, поэтому внедренный EntityManager используется повторно. Я ожидал, что когда транзакция завершится, диспетчер сущностей будет автоматически очищен. Но это не тот случай. Обычно Entity Manager возвращает правильное значение, но часто он возвращается и вместо этого возвращает старое значение из более ранней транзакции.
В качестве обходного пути я добавил стратегические операторы entityManager.clear() в методы чтения DAO, но это уродливо. Менеджеры сущностей должны очищаться после каждой транзакции.
Кто-нибудь испытал это? Есть ли правильное решение? Можно ли очищать диспетчер объектов после каждой транзакции?
Большое спасибо.
Я использую: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean и org.springframework.orm.jpa.JpaTransactionManager