繁体   English   中英

Spring Boot,多对一关系获取LAZY或EAGER

[英]Spring Boot, many to one relationship fetch LAZY or EAGER

两个具有双向一对多关系的实体。

实体A指向实体B的列表,其最多将是几个。 实体B有一个对A的反向引用。

当显示为JSON时,我期望看到A带有多个B或带有相应A的B.但这似乎取决于@OneToMany或@ManyToOne注释中的获取策略。

我读过的大多数内容都说@ManyToOne应该是LAZY,而@OneToMany应该是EAGER。 在列出实体A时,这种方法将起作用; 每个A和它的相关B都以JSON显示。

但是当列出B时,我收到了一个错误

类型定义错误:[simple type,class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor]; 嵌套异常是com.fasterxml.jackson.databind.exc.InvalidDefinitionException:没有为类org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor找到序列化器,也没有发现创建BeanSerializer的属性(为了避免异常,请禁用SerializationFeature.FAIL_ON_EMPTY_BEANS

将LAZY更改为EAGER可以解决问题。 但是,有了LAZY,我原本预计它会至少提出B记录。 错误令人惊讶。

我将添加两个实体定义使用JsonIdentityInfo(添加以防止无限递归),它使用SimpleObjectIdResolver。

所以,总而言之,我很困惑。 我可以让它“工作”,但不能确定为什么。

我读过的大多数内容都说@ManyToOne应该是LAZY,而@OneToMany应该是EAGER。 在列出实体A时,这种方法将起作用; 每个A和它的相关B都以JSON显示。

这不是应该做的,而是默认的。 这可以在@ManyToOne - 和@OneToMany -documentation中看到。 应该做什么因用例和用例而异。


例外:如果使用延迟加载定义关系,则插入代理对象,并在需要时从数据库中获取实际实体。 杰克逊试图序列化代理并失败。 这暗示了一个更深层的架构设计缺陷:为什么要尝试序列化数据库实体? 数据库和序列化过程之间应该至少有一层(例如通过DTO转换)。

即使序列化按预期工作(即获取缺失的实体),最有可能的是,加载实体的事务已经关闭,并且该过程将导致LazyInitializationException 如果你事先知道你总是需要获取关系,那就急切地提取它。 如果您只需要在某些情况下获取关系,请在JPQL中对提取进行编码,如果需要,可以在本机查询中对CriteriaQuery进行编码。 获取延迟加载的@OneToMany关系将导致N + 1问题 ,应该不惜一切代价避免这个问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM