避免对未获取的惰性对象进行 Jackson 序列化 [英] Avoid Jackson serialization on non fetched lazy objects

查看:18
本文介绍了避免对未获取的惰性对象进行 Jackson 序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的控制器,它返回一个 User 对象,这个用户有一个属性坐标,它具有休眠属性 FetchType.LAZY.

I have a simple controller that return a User object, this user have a attribute coordinates that have the hibernate property FetchType.LAZY.

当我尝试获取这个用户时,我总是要加载所有坐标来获取用户对象,否则当Jackson尝试序列化用户时抛出异常:

When I try to get this user, I always have to load all the coordinates to get the user object, otherwise when Jackson try to serialize the User throws the exception:

com.fasterxml.jackson.databind.JsonMappingException: 无法初始化代理 - 没有会话

com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy - no Session

这是因为 Jackson 试图获取这个未获取的对象.以下是对象:

This is due to Jackson is trying to fetch this unfetched object. Here are the objects:

public class User{

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
    @JsonManagedReference("user-coordinate")
    private List<Coordinate> coordinates;
}

public class Coordinate {

    @ManyToOne
    @JoinColumn(name = "user_id", nullable = false)
    @JsonBackReference("user-coordinate")
    private User user;
}

和控制器:

@RequestMapping(value = "/user/{username}", method=RequestMethod.GET)
public @ResponseBody User getUser(@PathVariable String username) {

    User user = userService.getUser(username);

    return user;

}

有没有办法告诉 Jackson 不要序列化未获取的对象?我一直在寻找 3 年前发布的其他答案,以实现 jackson-hibernate-module.但可能可以通过新的 jackson 功能实现.

There is a way to tell Jackson to not serialize the unfetched objects? I've been looking other answers posted 3 years ago implementing jackson-hibernate-module. But probably it could be achieved with a new jackson feature.

我的版本是:

  • 春季 3.2.5
  • 休眠 4.1.7
  • 杰克逊 2.2

提前致谢.

推荐答案

我终于找到了解决方案!感谢 indybee 给我一个线索.

I finally found the solution! thanks to indybee for giving me a clue.

教程 Spring 3.1、Hibernate 4 和Jackson-Module-Hibernate 为 Spring 3.1 及更早版本提供了一个很好的解决方案.但是由于Spring 3.1.2版本有自己的MappingJackson2HttpMessageConverter,功能与教程中的几乎相同,所以我们不需要创建这个自定义的HTTPMessageConverter.

The tutorial Spring 3.1, Hibernate 4 and Jackson-Module-Hibernate have a good solution for Spring 3.1 and earlier versions. But since version 3.1.2 Spring have his own MappingJackson2HttpMessageConverter with almost the same functionality as the one in the tutorial, so we don't need to create this custom HTTPMessageConverter.

使用 javaconfig 我们也不需要创建 HibernateAwareObjectMapper,我们只需要将 Hibernate4Module 添加到 Spring 的默认 MappingJackson2HttpMessageConverter已经有了并将其添加到应用程序的 HttpMessageConverters 中,因此我们需要:

With javaconfig we don't need to create a HibernateAwareObjectMapper too, we just need to add the Hibernate4Module to the default MappingJackson2HttpMessageConverter that Spring already have and add it to the HttpMessageConverters of the application, so we need to:

  1. WebMvcConfigurerAdapter 扩展我们的 spring 配置类并覆盖方法 configureMessageConverters.

  1. Extend our spring config class from WebMvcConfigurerAdapter and override the method configureMessageConverters.

在该方法上添加 MappingJackson2HttpMessageConverter,并在之前的方法中注册 Hibernate4Module.

On that method add the MappingJackson2HttpMessageConverter with the Hibernate4Module registered in a previus method.

我们的配置类应该是这样的:

Our config class should look like this:

@Configuration
@EnableWebMvc
public class MyConfigClass extends WebMvcConfigurerAdapter{

    //More configuration....

    /* Here we register the Hibernate4Module into an ObjectMapper, then set this custom-configured ObjectMapper
     * to the MessageConverter and return it to be added to the HttpMessageConverters of our application*/
    public MappingJackson2HttpMessageConverter jacksonMessageConverter(){
        MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();

        ObjectMapper mapper = new ObjectMapper();
        //Registering Hibernate4Module to support lazy objects
        mapper.registerModule(new Hibernate4Module());

        messageConverter.setObjectMapper(mapper);
        return messageConverter;

    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        //Here we add our custom-configured HttpMessageConverter
        converters.add(jacksonMessageConverter());
        super.configureMessageConverters(converters);
    }

    //More configuration....
}

如果你有一个 xml 配置,你也不需要创建你自己的 MappingJackson2HttpMessageConverter,但你需要创建教程中出现的个性化映射器 (HibernateAwareObjectMapper),所以你的 xml 配置应该是这样的:

If you have an xml configuration, you don't need to create your own MappingJackson2HttpMessageConverter either, but you do need to create the personalized mapper that appears in the tutorial (HibernateAwareObjectMapper), so your xml config should look like this:

<mvc:message-converters>
    <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <property name="objectMapper">
            <bean class="com.pastelstudios.json.HibernateAwareObjectMapper" />
        </property>
    </bean>
</mvc:message-converters>

希望这个答案是可以理解的,并帮助有人找到解决这个问题的方法,任何问题都可以随时提出!

Hope this answer be understandable and helps someone find the solution for this problem, any questions feel free to ask!

这篇关于避免对未获取的惰性对象进行 Jackson 序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆