当jackson序列化json对象时,如何防止hibernate5从延迟抓取?

时间:2017-08-17 20:12:05

标签: spring hibernate spring-boot jackson hibernate-5.x

我目前正在运行一个spring-boot应用程序,其中端点返回存储在数据库中的特定对象的Page。为了我们的目的,我们可以调用该对象" x"。在" x"有一个对象列表设置为延迟提取。

@Entity
@DynamicUpdate
class x {

      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private Integer id;

      @JsonIgnore
      @OneToMany(mappedBy = "x", cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
      private List<y> lazilyFetchedList;

      @Override
      public Integer getId() {
           return id;
      }

      public void setId(Integer id) {
           this.id = id;
      }

      @JsonIgnore
      public List<y> getLazilyFetchedList() {
           return lazilyFetchedList;
      }

      public void setLazilyFetchedList(List<y> lazilyFetchedList) {
           this.lazilyFetchedList = lazilyFetchedList;
      }
}

我设置了@JsonIgnore,因为我不希望在GET通话时将lazilyFetchedList发送到客户端。

我的问题是,即使杰克逊成功忽略字段作为查看JSON响应的客户端。但是,当序列化Java对象&#34; x&#34;时,hibernate 仍会提供额外的查询来获取lazilyFetchedList。 (即使杰克逊没有使用结果)。

我已经尝试过Avoid Jackson serialization on non fetched lazy objects的答案,但没有一个答案似乎有用。

以下是我的控制器的样子:

    @RequestMapping(value = "/{id}/x", method = RequestMethod.GET)
    public ApiResponse<?> findX(@PathVariable Integer id, PagingInfo info) {
        Page<x> page = repo.findX(id, toPageable(info));
        return toResponse(page, FIND_LIST_STATUS);
    } 

这是我对象映射器的配置:

@Configuration
@EnableWebMvc
public class ApiWebConfig extends WebMvcConfigurerAdapter {

@Bean
public ObjectMapper objectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    configureDefaultObjectMapper(objectMapper);
    customizeObjectMapper(objectMapper);
    return objectMapper;
}

public static void configureDefaultObjectMapper(ObjectMapper objectMapper) {
    objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
    objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);

    objectMapper.registerModule(new Hibernate5Module());

    JavaTimeModule javaTimeModule = new JavaTimeModule();
    javaTimeModule.addSerializer(ZonedDateTime.class, ZonedDateTimeSerializer.INSTANCE);
    javaTimeModule.addSerializer(OffsetDateTime.class, OffsetDateTimeSerializer.INSTANCE);
    objectMapper.registerModule(javaTimeModule);
}

/**
 * Only register a json message converter
 */
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.clear();

    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON, ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON));
    converter.setObjectMapper(objectMapper());

    converters.add(converter);
}
}

版本:

  • Spring-Boot 1.5.3
  • 杰克逊2.8.6
  • Hibernate 5.0.11.Final
  • jackson-datatype-hibernate5 2.9.0

1 个答案:

答案 0 :(得分:5)

将以下依赖项添加到pom.xml:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-hibernate5</artifactId>
</dependency>

(如果版本不受spring-boot-dependencies或spring-boot-starter-parent管理,请添加该版本) 将以下代码添加到spring配置类:

@Bean
protected Module module() {
    return new Hibernate5Module();
}

使用以下导入:

import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;