gpt4 book ai didi

spring - 延迟加载有效,但不应该

转载 作者:行者123 更新时间:2023-12-04 17:53:01 25 4
gpt4 key购买 nike

本题上下文在spring-boot中,使用spring-data-jpa和hibernate。

同事写了一个@Service,并用@Transactional注解了服务方法。服务方法加载实体,随后命中一对多延迟加载集合 (fetch = FetchType.LAZY)。服务方法由一些自定义委托(delegate)者调用,我将回过头来。当从 @RestController 端点调用时,这工作正常。

当我从 Camel 路线(再次通过自定义委托(delegate)者)调用服务时,它遇到了延迟初始化异常。

在挖掘时,发现该服务实现了一个接口(interface),自定义委托(delegate)器查找该服务(它被注入(inject),因此具有适当的代理)并调用一个方法在实际上是java-8默认方法的接口(interface)上。这个默认方法然后在本地调用 @Transactional 方法。

所以问题来了:- 这是一个本地方法调用,所以 @Transactional 注释的方面/代理没有完成(我们使用 aspectJAutoProxy)所以这个方法不是在一个交易,所以延迟加载应该失败。并仔细检查,还通过 @Scheduled 注释进行了尝试:相同的行为。像它应该的那样呕吐。

我的问题:那么为什么它在从 @RestController 调用时有效?这让我抓狂!

其余 Controller 端点上没有事务注释。

我使用 TransactionSynchronizationManager.isActualTransactionActive() 向服务添加了一些调试代码,它表明在任何情况下都没有事务,即使是通过 Controller 端点调用也是如此。

那么为什么从 Controller 调用时延迟加载会起作用?我转储了所有 SQL,并且在任何时候都没有加载惰性集合,因此它们不在任何 hibernate 缓存中。

我记得有一次读到延迟加载是一个提示,而不是一个命令,但仍然......为什么它在那种情况下起作用?

最佳答案

在多次被这个问题迷惑之后,偶然发现了答案:

sprint-boot 正在通过 OpenEntityManagerInView 拦截器在我们背后执行 open-entity-manager-in-view。不知道这是怎么回事。

请参阅 Vlad Mihalcea 的出色回答 https://stackoverflow.com/a/48222934/208687

关于spring - 延迟加载有效,但不应该,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42942364/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com