【问题标题】:spring rest lazy loading with hibernate使用休眠的弹簧休息延迟加载
【发布时间】:2017-09-13 06:16:20
【问题描述】:

我正在尝试使用 hibernate 开发 spring rest api。 在谷歌搜索后,我没有找到延迟加载的解决方案。 我有两个如下实体:

大学.java

@Entity()
@Table(schema = "core", name = "university")
public class University extends BaseEntity {

    private String uniName;
    private String uniTelephon;


    @LazyCollection(LazyCollectionOption.FALSE)
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "university", cascade = CascadeType.ALL)
    @JsonManagedReference
    private List<Student> students;

//setter and getter
}

学生.java

@Entity
@Table(schema = "core",name = "student")
public class Student {

    @Id
    @GeneratedValue            
    private long id;        

    private String firstName;        

    private String lastName;        

    private String section;

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "UNIVERSITY_ID",nullable = false)
    @JsonBackReference
    private University university;
    // setter and getter
}

任何我的休息终点

@GetMapping("/list")
public ResponseEntity list() throws Exception {
    // I need to return just Universities But it return it eagerly with their students
    return new ResponseEntity(this.universityService.findAll(), HttpStatus.OK);
}

调用rest api后,返回大学和所有学生。

有没有办法告诉杰克逊不要序列化未获取的对象或集合?

有人可以帮助我提供经过验证的解决方案吗?

【问题讨论】:

  • 虽然接受的答案是正确的,但更好的答案是不要将您的实体返回给客户。首先将它们转换为数据传输对象(DTO)并将这些 DTO 对象发送回客户端。

标签: json hibernate lazy-loading one-to-many spring-rest


【解决方案1】:

尝试添加以下依赖项(取决于您的休眠版本):

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-hibernate5</artifactId>
    <version>${jackson.version}</version>
</dependency>

然后(假设您有基于 Java 的配置)在 WebMvcConfigurerAdapter 类中添加以下内容:

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.add(jackson2HttpMessageConverter());
}

@Bean
public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() {
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setObjectMapper(this.jacksonBuilder().build());

    return converter;
}

public Jackson2ObjectMapperBuilder jacksonBuilder() {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();

    Hibernate5Module hibernateModule = new Hibernate5Module();

    hibernateModule.configure(Feature.FORCE_LAZY_LOADING, false);

    builder.modules(hibernateModule);

    // Spring MVC default Objectmapper configuration
    builder.featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    builder.featuresToDisable(MapperFeature.DEFAULT_VIEW_INCLUSION);

    return builder;
}

它应该强制 Jackson 的 objectMapper 不获取延迟加载的值。

【讨论】:

  • 其通过以下异常 HTTP 状态 500 - 无法写入内容:未能延迟初始化角色集合:a2.asena.cashModel.University.students,无法初始化代理 - 无会话(通过参考链:java.util.ArrayList[0]->a2.asena.cashModel.University["students"]);嵌套异常是 com.fasterxml.jackson.databind.JsonMappingException:未能延迟初始化角色集合:a2.asena.cashModel.University.students,无法初始化代理 - 无会话(通过引用链:java.util.ArrayList[ 0]->a2.asena.cashModel.University["students"])
  • 对于上述异常解决方案是覆盖 Appinitializer 中的过滤器 @Override protected Filter[] getServletFilters() { return new Filter[]{new HiddenHttpMethodFilter(), new MultipartFilter(), new OpenEntityManagerInViewFilter()};是
  • 有些文章说这不是正确的解决方案
  • 我不能说这是否是一个合适的解决方案,但我不知道其他人。我更改了答案以使其与 Spring MVC 一起使用,之前初始化 ObjectMapper 的方式是错误的。
猜你喜欢
  • 2011-06-15
  • 1970-01-01
  • 2016-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
相关资源
最近更新 更多