Spring Boot 中的 Hibernate 无法懒惰地初始化角色集合,无法初始化代理 - 没有 Session 异常
Posted
技术标签:
【中文标题】Spring Boot 中的 Hibernate 无法懒惰地初始化角色集合,无法初始化代理 - 没有 Session 异常【英文标题】:Hibernate in Spring Boot failed to lazily initialize a collection of role, could not initialize proxy - no Session exception 【发布时间】:2021-11-27 17:23:12 【问题描述】:我有三个实体,其中两个每个都包含第三个的集合。当我通过使用第三个实例创建两个“拥有”实体来设置它们时,只有一个可以正常工作。另一个在添加时抛出此异常,即使集合的设置方式完全相同:
“拥有”实体:
@Entity
class Source(
@OneToMany(mappedBy = "source", cascade = [CascadeType.ALL])
var targets: MutableSet<Target> = mutableSetOf(),
@Id @GeneratedValue
var id: Long? = null,
)
fun addTarget(target: Target)
targets.add(target)
target.source = this
@Entity
class Job(
@OneToMany(mappedBy = "job", cascade = [CascadeType.ALL])
var targets: MutableSet<Target> = mutableSetOf(),
@Id @GeneratedValue
var id: Long? = null,
)
fun addTarget(target: Target)
targets.add(target) // exception actually thrown here
target.job = this
共同“拥有”的实体:
@Entity
class Target(
@ManyToOne var source: Source? = null,
@ManyToOne var job: Job? = null,
@Id @GeneratedValue var id: Long? = null
)
设置如下:
@PostConstruct
@Transactional
fun init()
val initialJob = Job()
initialJob.targets = mutableSetOf() // no idea why this is necessary, but without it I get the exception
jobRepository.save(initialJob)
val source = Source()
sourceRepository.save(source)
val target = Target()
source.addTarget(target) // this works fine
initialJob.addTarget(target) // but this doesn't unless I initialize the set above
targetRepository.save(target)
sourceRepository.save(source)
jobRepository.save(initialJob)
我很困惑为什么我需要手动初始化 Job 实体上的集合,而不是 Source 实体上的集合,因为在我看来这些关系是完全相同的。另外,Job 实体已经在其构造函数中初始化集合。
【问题讨论】:
【参考方案1】:我认为问题在于@PostConstruct
和@Transactional
的组合。
@PostConstruct
在postProcessBeforeInitialization
阶段之后被调用。在 postProcessAfterInitialization
阶段创建 @Transactional
代理时。
因此,该方法未包装在一个事务中,您会收到no session
异常。
您可以尝试使用@EventListener
方法。
@Component
class SomeListener
@Autowired
private MyService service;
@EventListener
public void onInit(ContextRefreshedEvent e)
service.init();
【讨论】:
很有趣。实际上,我最终进行了重构以完全避免该问题,但这是一个非常有趣的想法。你也许是对的。我会看看我是否可以设置一个场景来测试它。谢谢! 很高兴能帮到你。请把我的帖子标记为答案好吗? 是的,做到了。我从服务的 init() 方法中删除了 @PostConstruct 注释,并从事件侦听器中显式调用它。谢谢!以上是关于Spring Boot 中的 Hibernate 无法懒惰地初始化角色集合,无法初始化代理 - 没有 Session 异常的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot Hibernate 将数据插入 Postgres 中的错误列
无法从 Spring Boot REST 中的 Hibernate POJO 返回 JSON
Hibernate中的ManyToMany映射引用错误(由api生成的表名)表Spring Boot
动态数据源作为 Spring Boot + Hibernate 中的第二个数据源