【发布时间】:2018-01-26 09:42:11
【问题描述】:
我目前正在运行一个 spring-boot 应用程序,其中端点返回存储在数据库中的特定对象的页面。出于我们的目的,我们称该对象为“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 响应的客户端,jackson 成功忽略了该字段。但是,当序列化 Java 对象“x”时,hibernate 仍然会进行额外的查询来获取 lazilyFetchedList(即使 jackson 没有使用结果)。
我已经尝试了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
- 休眠 5.0.11.Final
- jackson-datatype-hibernate5 2.9.0
【问题讨论】:
-
如果删除 getter/setter 会发生什么?
-
不要使用实体类,而是为 json 创建 pojo..
-
问题是,我的项目中有很多实体。因此,为每个人创建一个 pojo 将不是一个可行的解决方案,而且我不想实现一个需要在两个不同位置更改字段的解决方案,因为如果有人要更新该实体,代码很可能会中断。我想要一个由图书馆自己处理的更通用的解决方案。
标签: spring hibernate spring-boot jackson hibernate-5.x