当前位置: 首页 > 知识库问答 >
问题:

如何在Spring数据rest@RepositoryEventHandler@HandleAfterLinkSave中解决Lazy初始化异常?

袁单鹗
2023-03-14

我有一个SpringDataREST应用程序,它具有类型匹配和舍入之间的关系

@Entity
public class Match {

    @OneToMany
    private List<Round> rounds;
    ...
}

在比赛和回合之间创建链接时,例如

curl -X PUT -d "http://localhost:8080/rounds/2" -H "Content-Type:text/uri-list" http://localhost:8080/matches/1/rounds;

我用EventHandler捕捉到这一点,对我的域模型进行一些更新:

public class MatchEventHandler

    @HandleAfterLinkSave
    public void handleLinkSave(Match match, List<Round> rounds) {
        ...
}

我需要访问第二个参数才能进行更新,但这样做,例如使用rounds.get(0)返回

org.hibernate.懒惰初始化集合失败,无法初始化代理-无会话

阅读关于Hibernates LazyInitializationExceptions的其他线程,我主要看到了建议的三种方法:

  1. 使用Hibernate.initialize()-我不知道我可以调用哪个方法,它会给Hibernate框架添加一个丑陋的依赖
  2. 将控制器方法放入事务中-我知道Spring data已经将所有东西放入事务中。另外,由于这是一个Spring数据Rest应用程序,我没有使用任何控制器或服务层,因此我不知道到底要把什么放入事务中。
  3. 设置FetchType。渴望关系——尽管不是一个真正有效的解决方案,但我确实尝试过。在这种情况下,@HandleAfterLinkSave方法的第二个参数是一个空列表,因此它也不会传递预期的结果。

共有1个答案

唐利
2023-03-14

属性引用在以下Spring类中处理:

org.springframework.data.rest.webmvc.仓库

虽然大多数时候它工作得很好,但它在这里或那里都有缺陷。或者让我们这样说:它有一些有趣的行为...(在过去的两年里,我花了几个月的时间来创建Spring Data Rest的改进版本)。

如果请求方法是POST或PATCH,则第2个参数包含更新的集合。但如果使用PUT方法,则它包含原始集合。

(此外,如果您的主实体中有多个属性集合,则无法确定修改了哪个集合。对于映射类型属性,也有一些可疑的结果,但这是另一种情况。)

因此,如果您在RoundRepository中创建一个存储库方法,并使用它重新加载集合,那么最好的解决方案是:

@RestResource(exported = false)
List<Round> findAllByMatch(Match match);

顺便说一句关于选项2,请阅读本主题!

 类似资料:
  • 我的 centos7 虚拟机中安装的 wiki.js + postgresql 运行初始化页面时出现下面提示,要如何解决

  • 我试图在登录后(从登录成功过滤器)获取用户的配置文件数据,但我发现延迟加载数据的异常。请参见以下示例代码: AuthenticationSuccessHandler。JAVA 用户服务。JAVA 用户模型。JAVA 用户登录响应to.java 当在中序列化UserLoginResponseDto类型的对象时,我会看到以下错误消息- org.hibernate.懒惰初始化角色集合失败:UserMod

  • 在我的Spring Boot项目中,两个REST APIendpoint需要一个初始化需要几分钟的类。正因为如此,启动REST API需要几分钟的时间。 有没有可能(使用Spring Boot)使这些endpoint异步初始化,即所有其他endpoint立即初始化,并且REST API开始工作,并且这些endpoint在它们所需的类被初始化并且在此之前用户根本不可用时被初始化? 在Spring B

  • 今天我学习了一个教程,作者在其中解释了hibernate关联一对多/多对一。我不想把他所有的代码都写在这里。所以,我试着把重点放在。。。 我们有两个实体:“团队”和“球员” 在代码中,我们有: 和 我最感兴趣的是回迁的类型。所以,我们加入了一支球队和一些属于这支球队的球员。我的DAO类标记为 现在我想从数据库中加载充满玩家集合的团队实体。 结果是,我将得到LazyInitializationExc

  • SOFABoot 提供了模块并行启动以及 Spring Bean 异步初始化能力,用于加快应用启动速度。本文介绍如何使用 SOFABoot 异步初始化 Spring Bean 能力以提高应用启动速度。 使用场景 在实际使用 Spring/Spring Boot 开发中,一些 Bean 在初始化过程中执行准备操作,如拉取远程配置、初始化数据源等等。在应用启动期间,这些 Bean 会增加 Spring

  • 场景:我在Spring中开发了一个使用mysql 8数据库的微服务。这个数据库必须被初始化(创建一个数据库、一些表和数据)。在我的主机上,我用data.sql和schema.sql脚本初始化了数据库。问题是,我必须设置: 第一次执行。这将以我想要的方式初始化我的数据库。对于以后的运行,我必须对该命令进行注释。非常难看的解决方案,但我找不到更好的解决方案,我现在没有得到这个问题的答案。我认为测试它是