【发布时间】:2019-03-20 13:55:31
【问题描述】:
我的项目曾经到处都有很多@Transactional 方法。现在由于业务逻辑,我不想在遇到问题时回滚,而是想将我的对象设置为错误状态(也就是保存在数据库中,所以绝对不是回滚),所以我删除了一些 @Transactional 开始。
现在的问题是有延迟加载没有会话,因此产生了 LazyInitializationException。
下面是我目前的故障排除和解决方案:
我们使用的是注解配置,所以这里没有xml配置。
对于使用数据库的每个操作,都会创建一个EntityManager(定义为属性并在服务中@Autowired)然后删除(我在添加配置时可以在日志中清楚地看到它们),根据 Spring 文档,这显然是正常的。
将 @PersistenceContext 或 @PersistenceUnit 与 EntityManagerFactory 或 EntityManager 一起使用都不起作用。
我可以加载我想与 Hibernate.initialize() 一起使用的延迟加载属性,然后它不会产生 LazyInitializationException。
现在我的问题是:为什么休眠不能自己做呢?对我来说,如果我使用延迟加载,我希望 Hibernate 创建一个会话(在执行 Hibernate.initialize() 时他似乎完全能够做到这一点)来自动加载日期,这对我来说似乎微不足道。
是否有一种方法可以生成一个新的实体管理器以在我的方法中使用,这样 Hibernate 就不会一直创建和重新创建一个?我真的觉得我缺少一些关于 Hibernate、延迟加载和会话的基本知识,这使得整个混乱变得不那么复杂。
这是一个例子:
@Entity
@Table(name = "tata")
public class Tata {
@Id
@Column(name = "tata_id")
private Long id;
// getter / setter etc
}
@Entity
@Table(name = "toto")
public class Toto {
@Id
@Column(name = "toto_id")
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "tata_id")
private Tata tata;
// getter / setter etc
}
@Service("totoManager")
public class TotoManager extends GenericManagerImpl {
@Autowired
private EntityManager entityManager;
@Autowired
private TotoRepository totoRepository;
public void doSomethingWithTotos() throws XDExceptionImpl {
List<Toto> totos = this.totoRepository.findAll();
for (toto toto : totos) {
// LazyInitializationException here
LOGGER.info("tata : " + toto.getTata().getId());
}
}
}
【问题讨论】:
-
您希望休眠何时初始化会话?
-
当我想完全访问 tata 时,因为根据定义它没有加载,它需要到达数据库来加载它
标签: java hibernate spring-boot lazy-loading