【发布时间】:2016-04-10 10:47:27
【问题描述】:
最新的带有 JPA 和 Hibernate 的 Spring Boot:我正在努力理解事务、持久性上下文和休眠会话之间的关系,而且我无法轻易避免可怕的无会话延迟初始化问题。
我在一个事务中更新一组对象,然后我想遍历这些对象,在一个单独的事务中处理它们——看起来很简单。
public void control() {
List<> entities = getEntitiesToProcess();
for (Entity entity : entities) {
processEntity(entity.getId());
}
}
@Transactional(value=TxType.REQUIRES_NEW)
public List<Entity> getEntitiesToProcess() {
List<Entity> entities = entityRepository.findAll();
for (Entity entity : entities) {
// Update a few properties
}
return entities;
}
@Transactional(value=TxType.REQUIRES_NEW)
public void processEntity(String id) {
Entity entity = entityRepository.getOne(id);
entity.getLazyInitialisedListOfObjects(); // throws LazyInitializationException: could not initialize proxy - no Session
}
但是,我遇到了一个问题,因为(我认为)两个事务都使用了相同的休眠会话。当我在第二个事务中调用 entityRepository.getOne(id) 时,我可以在调试器中看到我返回的对象与第一个事务中 findAll() 返回的对象完全相同,而没有数据库访问。如果我理解正确,是休眠缓存在做这个吗?如果我随后在我的对象上调用需要延迟评估的方法,则会收到“无会话”错误。我认为缓存和会话是链接的,所以这是我的第一个困惑。
如果我删除所有的@Transactional 注释,或者如果我在控制方法上放置一个@Transactional,它都运行良好,但是数据库提交直到控制方法完成才完成,这显然不是我想要的。
所以,我有几个问题:
- 如何使休眠会话与我的事务范围保持一致?
- 使用 JPA 和声明式事务管理在循环中执行分离事务的良好模式是什么?
我想保留声明式风格(即没有 xml),并且不想做任何特定于 Hibernate 的事情。
任何帮助表示赞赏!
谢谢
马库斯
【问题讨论】:
标签: spring hibernate jpa transactions spring-data-jpa