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

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

问题描述

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



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


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


这是由于杰克逊试图获取这个未获取的对象。以下是对象:

  public class User {

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

$ b $ public class Coordinate {

@ManyToOne
@JoinColumn(name =user_id,nullable = false)
@JsonBackReference (用户坐标)
私人用户用户;
}

和控制器:

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

User user = userService.getUser(username);

返回用户;


$ / code>

有一种方法可以告诉杰克逊不要序列化未提取对象?我一直在寻找3年前发布的其他解决方案,实现jackson-hibernate-module。但可能它可以通过一个新的杰克逊功能实现。



我的版本是:


  • Spring 3.2.5

  • Hibernate 4.1.7

  • Jackson 2.2


在此先感谢。

解决方案

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



教程对Spring 3.1和更早版本都有很好的解决方案。但是从3.1.2版开始,Spring拥有自己的 MappingJackson2HttpMessageConverter ,其功能与本教程中的几乎相同,因此我们不需要创建此自定义HTTPMessageConverter。



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


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

  2. 在该方法中,将 MappingJackson2HttpMessageConverter 添加到previus方法中注册的 Hibernate4Module

    >

我们的配置类应该如下所示:

  @Configuration 
@EnableWebMvc
public class MyConfigClass extends WebMvcConfigurerAdapter {

//更多配置....

/ *在这里,我们将Hibernate4Module注册到一个ObjectMapper中,然后将这个自定义配置的ObjectMapper
*设置为MessageConverter,并将它返回给我们的应用程序的HttpMessageConverters * /
public MappingJackson2HttpMessageConverter jacksonMessageConverter(){
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();

ObjectMapper mapper = new ObjectMapper();
//注册Hibernate4Module以支持懒惰对象
mapper.registerModule(new Hibernate4Module());

messageConverter.setObjectMapper(mapper);
返回messageConverter;


$ b @Override
public void configureMessageConverters(List< HttpMessageConverter<>>转换器){
//这里我们添加我们的自定义配置HttpMessageConverter
转换器.add(jacksonMessageConverter());
super.configureMessageConverters(转换器);
}

//更多配置....
}

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

 < 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>

希望这个答案是可以理解的,并且可以帮助别人找到解决这个问题的办法,任何问题都可以问!

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

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: could not initialize proxy - no Session

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;
}

And the controller:

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

    User user = userService.getUser(username);

    return user;

}

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.

My versions are:

  • Spring 3.2.5
  • Hibernate 4.1.7
  • Jackson 2.2

Thanks in advance.

解决方案

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

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.

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. Extend our spring config class from WebMvcConfigurerAdapter and override the method configureMessageConverters.

  2. 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....
}

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天全站免登陆