【问题标题】:@LazyLoading and JsonOutput@LazyLoading 和 JsonOutput
【发布时间】:2017-04-24 03:45:29
【问题描述】:

从事一个使用 Spring/JPA/Rest 的项目。 我们有一个类,它有一个 @OneToMany 字段(在下面的示例中说 Student),它被标记为 LAZY 加载。但是,当我们在 postman 中测试输出时,我们会看到课程的完整 json 和所有学生的详细信息。

public class CourseList{

private String Course;
//other fields

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)    
private <Set>Student students;

//Getters and Setters

}

我对延迟加载的理解是,仅在对特定字段的显式调用时才会获取数据库。我们应该期望只看到 json 中出现的课程详细信息,而不是地址详细信息。为什么我们也会看到地址详细信息?

如果我对 LazyLoading 的理解不正确,或者由于某种原因它是否不适用于这种情况,有人可以帮忙澄清一下吗?谢谢。

【问题讨论】:

  • 你使用 Spring Data Jpa 吗?
  • 是的,Spring Data JPA。

标签: java json spring jpa jackson


【解决方案1】:

您的 JSON 库将递归读取对象的所有属性以生成输出。所以它正在访问学生集。

根据我的经验,这里有三种可能的结果:

  1. JSON 序列化发生在 JPA 会话之外,因此对象分离。由于学生集是延迟加载的,因此您将收到异常。

  2. JSON 序列化发生在 JPA 会话中,因此当 JSON 库访问学生集时,将从数据库中获取数据。

  3. JSON 序列化发生在 JPA 会话之外,但您以某种方式访问​​了在此之前和 JPA 会话内部设置的学生。数据已提取并可在分离的对象上使用。

我遇到了这个问题,我强制使用第三个选项。我的第一次尝试给了我异常(选项 1),但后来我强制从延迟加载的集合中读取,只是为了获取 JSON 序列化的数据。

【讨论】:

  • 在第 2 点中,您是说对 LAZY 对象也强制进行 JSON 序列化吗?这违背了 LAZY 的目的,还是像 Postman 这样的工具正在做这种强制加载?
  • 您的 JSON 库 对延迟加载一无所知。答案本质上就是这样。在没有任何进一步的处理指令的情况下,它会尝试像任何其他字段一样序列化惰性字段:这会触发数据库加载,这可能会或可能不会成功,具体取决于您的 JPA 提供程序和其他各种事情。这就是为什么存在 Jackson Hibernate 模块来帮助解决此类问题的原因:github.com/FasterXML/jackson-datatype-hibernate
【解决方案2】:

Spring Boot 注册了一个 OpenEntityManagerInViewInterceptor。 Spring boot 默认配置spring.jpa.open-in-view = true。 如果您想禁用该行为,请添加配置spring.jpa.open-in-view = false

注册 OpenEntityManagerInViewInterceptor。绑定一个 JPA EntityManager 到整个请求处理的线程。

【讨论】:

  • 谢谢@jackk!这似乎是正确的答案。但是,关于为什么会发生这种情况的一些细节可以帮助我和其他稍后阅读此线程的人。我用谷歌搜索了一下,发现这个很好的资源可以解释 hibernate 和 jpa 中的这个问题,但在 eclipselink 中没有问题。 vard-lokkur.blogspot.in/2010/12/…
【解决方案3】:
// ^_^?
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)    
public Link Student student;

你想返回CourseList包括List&lt;Student&gt;,你需要创建ResponseStudent实体你必须确保没有@ManyToOneCourseList,否则会发生StackOverflow错误。

本教程也提到了那个问题:Spring Data : JPA (Hibernate) One To Many Relationships and N+1 Query Problem

【讨论】:

  • 恐怕你误解了我的问题。我知道无限循环问题(链接所指)。我的问题是关于为什么邮递员 JSON 输出在结果中显示延迟加载的学生对象
猜你喜欢
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多