Spring Boot 2中惰性对象序列化期间没有会话

Posted

技术标签:

【中文标题】Spring Boot 2中惰性对象序列化期间没有会话【英文标题】:No session during serialization of lazy objects in Spring Boot 2 【发布时间】:2018-12-08 15:30:57 【问题描述】:

我正在将我的 Spring Boot REST API 从 1.5.4 迁移到 2.0.3。

这是我的两个实体,其中一个的存储库和访问它们的控制器:

Parent.java

@Entity
@Table(name = "PARENT")
public class Parent implements Serializable 

    @Id
    @GeneratedValue
    @Column(name = "ID")
    private Long id;

    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
    private List<Child> children;

Child.java

@Entity
@Table(name = "CHILD")
public class Child implements Serializable 

    @Id
    @GeneratedValue
    @Column(name = "ID")
    private Long id;

    @Column(name = "PARENT_ID")
    private Long parentId;

    @JsonIgnore
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "PARENT_ID")
    private Parent parent;

    @Column(name = "name")
    private String name;

ParentRepository.java

public interface ParentRepository extends JpaRepository<Parent, Long> 


ParentController.java

@RestController
@RequestMapping("/parents")
public class ParentController 

    @Autowired
    private ParentRepository parentRepository;

    @RequestMapping(method = RequestMethod.GET)
    public List<Parent> getParents() 
        return parentRepository.findAll();
    


@RestController 类中似乎不再有活动会话,因为

parentRepository.findAll().get(0).getChildren().get(0).getName();

现在抛出一个

LazyInitializationException: failed to lazily initialize a collection of role: com.mycompany.myapplication.entity.Parent.children, could not initialize proxy - no Session

这可以通过在控制器方法或控制器类上设置@Transactional 注解来解决。


但是,我遇到的问题是关于延迟加载的children

如果我运行上面的示例代码,即使使用 @Transactional 注释,我也会得到相同的异常,但嵌套了

com.fasterxml.jackson.databind.JsonMappingException

这是由于 JSON 的序列化发生在控制器之外,因此在活动会话之外。

有一个丑陋的解决方法,通过在退出方法之前从每个 child 读取一些数据:

@RequestMapping(method = RequestMethod.GET)
public List<Parent> getParents() 
    List<Parent> parents = parentRepository.findAll();
    parents.stream()
        .flatMap(p -> p.getChildren().stream())
        .forEach(Child::getName);
    return parents;

这可行,但非常难看,并且增加了很多样板。

另一种解决方案是将所有实体映射到 DTO,然后再将它们返回给客户端。但是这个解决方案为我的应用程序添加了另一个我不想要的层。


有没有办法确保在实体的自动序列化期间存在活动会话?

【问题讨论】:

【参考方案1】:

是啊……

在迁移期间我之前设置过

spring.jpa.open-in-view = false

因为我在日志中看到了一个关于它的新警告。此设置会删除我想要帮助添加的活动会话...

删除此设置并使用默认设置 (true) 完全解决了我的问题。

【讨论】:

请注意这个问题***.com/a/48222934/5380322

以上是关于Spring Boot 2中惰性对象序列化期间没有会话的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 2 没有序列化 LocalDateTime

有没有办法让 Spring Boot 反序列化以反序列化测试中的对象?

spring boot 源码赏析之事件监听

在 Spring Boot 中使用 Jackson 反序列化 Date 对象

Spring Boot存储库在测试期间无法正常工作

错误:惰性类的 Getter 不能是最终的 Kotlin Spring Boot