Нет гибернации сеанса в @PostConstruct

Класс MyDao имеет методы для выполнения целых задач сохранения через Hibernate SessionFactory, он отлично работает.

Я ввожу MyDao в MyService, как видно выше, но когда метод @PostConstruct init() вызывается после введенного MyDao (при отладке я вижу, что MyDao хорошо введен), получаю следующее исключение Hibernate:

org.hibernate.HibernateException: сеанс не найден для текущего потока

Моя реализация сервиса.

@Service("myService")
@Transactional(readOnly = true)
public class MyServiceImpl implements MyService {

    @Autowired
    private MyDao myDao;
    private CacheList cacheList;

    @PostConstruct
    public void init() {

        this.cacheList = new CacheList();
        this.cacheList.reloadCache(this.myDao.getAllFromServer());
    }

    ...
}

СПОСОБ РЕШЕНИЯ

Как рекомендовал мне @Yogi выше, я использовал TransactionTemplate для получения одного действительного/активного сеанса транзакции, в этом случае я реализовал сквозной конструктор и отлично работает для меня.

@Service("myService")
@Transactional(readOnly = true)
public class MyServiceImpl implements MyService {

    @Autowired
    private MyDao myDao;
    private CacheList cacheList;

    @Autowired
    public void MyServiceImpl(PlatformTransactionManager transactionManager) {

        this.cacheList = (CacheList) new TransactionTemplate(transactionManager).execute(new TransactionCallback(){

            @Override
            public Object doInTransaction(TransactionStatus transactionStatus) {

                CacheList cacheList = new CacheList();
                cacheList.reloadCache(MyServiceImpl.this.myDao.getAllFromServer());

                return cacheList;
            }

        });
    }

    ...
}

person Dani    schedule 05.03.2014    source источник
comment
В вашем коде есть «пустота», которую я не ожидал: public void MyServiceImpl. Должен ли это быть конструктор или это метод, который вы вызываете откуда-то еще?   -  person Angelo Fuchs    schedule 22.11.2017


Ответы (3)


Я не думаю, что на уровне @PostConstruct разрешена какая-либо транзакция, поэтому @Transactional здесь мало что даст, если только mode не установлено на aspectj в <tx:annotation-driven mode="aspectj" />. .

Согласно это обсуждение, которое вы можете использовать TransactionTemplate для запуска ручной транзакции внутри init() для привязки session, но если вы намерены строго придерживаться декларативной транзакции, вам нужно использовать ApplicationListener для регистрации события и пользователя < href="http://docs.spring.io/spring/docs/3.0.x/api/org/springframework/context/event/ContextRefreshedEvent.html" rel="nofollow noreferrer">ContextRefreshedEvent для запуска сделка.

person Yogesh    schedule 05.03.2014
comment
Большое спасибо, TransactionTemplate отлично работает для меня. ;) - person Dani; 05.03.2014

Убедитесь, что вы работаете под транзакцией. Я вижу аннотацию транзакции, но похоже, что вы пропустили активацию управления транзакциями с помощью аннотации с использованием тега <tx:annotation-driven/> в контексте spring.

person Shailendra    schedule 05.03.2014

Это происходит из-за того, что MyServiceImpl.init() вызывается Spring после создания компонента, связанного с MyServiceImpl, а аннотация @Transaction не используется для управления жизненным циклом сеанса.
Решением может быть рассмотрение Spring AOP вокруг методов, использующих кеш вместо @PostConstruct

person Luca Basso Ricci    schedule 05.03.2014