首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >避免杰克逊在SpringMVC中序列化Mybatis lazyload对象

避免杰克逊在SpringMVC中序列化Mybatis lazyload对象
EN

Stack Overflow用户
提问于 2018-03-26 16:22:39
回答 2查看 740关注 0票数 1

我有一个由Spring MVC框架构建的RESTful项目,带有Mybatis ORM。

有两个表,Book和Author,具有一对多关系。

我启用了延迟加载,这样当我查询Book时,它不会查询Author,除非我调用book.getAuthor()方法,一切都很正常。

mybatis-config.xml:启用延迟加载

BookMapper.xml

然而,当RESTful控制器返回Book对象时,它使用Jackson将Book对象传递给json,并触发mybatis加载Author对象。

控制器:在第30行,它只查询Book。

在第31行之后,它还查询Author

有没有办法防止mybatis在RESTful控制器返回json时触发延迟加载?

EN

回答 2

Stack Overflow用户

发布于 2018-03-28 05:49:16

问题不在mybatis。问题出在序列化上。如果属性被查询,mybatis别无选择,只能加载属性。

解决方案是配置序列化,这样authors属性就不会序列化。

例如,可以使用Jackson MixIns来完成此操作

首先,创建用于指定附加配置的mix-in:

代码语言:javascript
复制
abstract class NoAuthorsMixIn {
   @JsonIgnore abstract List<Author> authors();
}

然后,您需要将此混入添加到spring使用的jackson映射器配置中。确切的方式取决于您使用的是xml配置还是java配置。对于java配置,如下所示:

代码语言:javascript
复制
@Configuration
public class JacksonConfiguration {

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.addMixIn(Book.class, NoAuthorsMixIn.class);
        return mapper;
    }
}

请注意,这将禁用所有控制器方法中的authors序列化。如果您需要能够根据控制器和/或控制器方法来切换它,则设置会更加复杂(例如,查看this )。

票数 1
EN

Stack Overflow用户

发布于 2018-03-28 09:57:34

我找到了一个解决方案,不是最好的,但它是有效的。仍然期待一个更好的解决方案。

当杰克逊序列化图书对象时,它触发了Book.getAuthors(),Mybatis检测到Book.getAuthors()被调用,因此Mybatis通过Javassist代理执行延迟加载,如下所示:

请注意,“任何调用getter的人都会触发延迟加载”(红圈),这就是Jackson总是在序列化中触发延迟加载的原因!

为了解决这个问题,我修改了Book bean:

  1. 添加@JsonIgnore on Book.getAuthors(),防止杰克逊在Book.loadDetail()上调用getAuthors().
  2. Add @JsonGetter(value = "authors"),这样当杰克逊可以序列化作者时,就不会触发延迟加载。

结果如下:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49486951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档