当前位置: 首页 > 知识库问答 >
问题:

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

张森
2023-03-14

我目前正在运行一个spring boot应用程序,其中endpoint返回存储在数据库中的特定对象的页面。出于我们的目的,我们将该对象称为“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调用时将其发送给客户端。

我的问题是,即使jackson在查看JSON响应时成功地忽略了该字段。但是,当序列化Java对象“x”时,hibernate仍然会进行额外的查询以获取LazyFetchedList(即使jackson没有使用结果)。

我已经在未获取的懒惰对象上尝试了避免Jackson序列化的答案,但这些答案似乎都不起作用。

以下是我的控制器的外观:

    @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防尘套1.5.3

共有1个答案

桂阳文
2023-03-14

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

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

(如果版本不是由spring-boot-依赖项或spring-boot-starter-家长管理,请添加该版本)将以下代码添加到您的Spring配置类中:

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

有以下进口:

import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
 类似资料:
  • 我有这样一门课: 我知道基于typeToClassId的对象obj是什么类型,不幸的是只有在运行时才知道。 我想基于typeToClassId解析出obj——这里最好的方法是什么?注释似乎已经过时了,基于ObjectMapper的东西似乎是对的,但我很难弄清楚最好的方法可能是什么。 类似于类clazz=lookUpClassBasedOnId(typeToClassId)objectMapper的

  • 我想进一步说明这个问题是关于什么的,我已经漫游了一个小时了,但没有找到任何东西。 更糟糕的是,正如您所看到的,该属性是final(这就是为什么我热衷于通过反序列化在实例化时使用Jackson反射能力)。我已经阅读了关于以不同的方式注释setter和getter的潜在解决方案,但如果可能的话,我希望将此属性保留为最终属性。如果不可能,我会接受一个非最终财产。 我希望答案不建议自定义序列化/反序列化,

  • 我使用Spring并创建了一个REST服务。 这是我的控制器的一部分: 该人员的角色是延迟初始化的,当时不需要。当(1)被注释掉时,所有操作都将失败 org.springframework.http.converter.HttpMessageNotWritableException:无法写入JSON:无法延迟初始化角色集合:no.something.project.Person.roles,无法初

  • 问题内容: 我有这样的课: 我知道哪种类型的对象obj基于typeToClassId,不幸的是仅在运行时才知道。 我想根据typeToClassId解析obj- 最好的方法是什么?注解似乎已经消失了,基于ObjectMapper的东西似乎是正确的,但是我在弄清楚最好的方法是什么时遇到了麻烦。 类clazz = lookUpClassBasedOnId(typeToClassId)objectMap

  • 我有一个非常大的JSON文件太大,无法使用ObjectMapper.read值()到JsonNode的问题。我想在Android上使用杰克逊库解析大型JSON时使用内存不足错误的解决方案,除了JSON文件是一个具有字段名称的单个对象,因此我无法创建一个模型POJO来反序列化。 对象内部的每个属性都有相同的格式,我可以忽略这些内部对象的许多属性(我已经有了一个POJO类来建模)。如果JSON文件是一

  • 主要内容:1 编写核心类,2 运行测试本文讲解如何将一个Java对象序列化为一个json文件,然后读取该json文件读取回对象。在下面的示例中,我们创建Student类。使用Jackson存储到一个student.json文件,该文件拥有Student对象的JSON表示形式。 1 编写核心类 MainApp: 2 运行测试