如何响应 Spring RestController 返回 ManyToOne 双向 JPA 实体对象?

Posted

技术标签:

【中文标题】如何响应 Spring RestController 返回 ManyToOne 双向 JPA 实体对象?【英文标题】:How to return a ManyToOne Bidirectional JPA Entity Object in response of a Spring RestController? 【发布时间】:2021-11-12 15:19:50 【问题描述】:

我有 2 个实体用户和权限,它们具有双向多对一关系。 但是当我发送用户对象作为来自 RestController 的响应时,我得到了嵌套对象 IE。用户AuthorityUserAuthorityUserAuthority..

如何实现控制器必须只返回? 用户Authority

下面是我的 User 实体类:-

@Entity
public class User 

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long userId;

    private String username;
    private String password;
    private String mobileNo;

    @OneToMany(fetch =FetchType.EAGER , cascade = CascadeType.ALL, mappedBy = "user")
    private Set<Authorities> authorities;
    
    // non-parameterized and parameterized constructor and all getters and setters 


@Entity
public class Authorities implements GrantedAuthority 

    private static final long serialVersionUID = -2789840366318513805L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String authority;

    @ManyToOne
    private User user;

    // non-parameterized and parameterized constructor and all getters and setters 

@RestController
public class HomeController 
    
    @GetMapping(path = "/home")
    public @ResponseBody User home(@AuthenticationPrincipal User user)
        return user;
     

以下是我浏览器中的 sn-p:

    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.12.4.jar:2.12.4]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770) ~[jackson-databind-2.12.4.jar:2.12.4]

2021-09-18 00:45:17.935 ERROR 9340 --- [nio-8080-exec-7] s.e.ErrorMvcAutoConfiguration$StaticView : Cannot render error page for request [/home] as the response has already been committed. As a result, the response may have the wrong status code.

【问题讨论】:

【参考方案1】:

Authorities 类中,在User 字段上方添加@JsonIgnore

@ManyToOne
@JsonIgnore
private User user;

【讨论】:

以上是关于如何响应 Spring RestController 返回 ManyToOne 双向 JPA 实体对象?的主要内容,如果未能解决你的问题,请参考以下文章

spring Restcontroller 或 RepositoryRestResource 用啥

spring boot常用注解使用小结

Spring:RestController 和 Controller 的不同异常处理程序

Spring-Boot:同时处理多个请求

如何使用 spring 记录 RestTemplate 请求和响应?

如何在 Spring 中缩小动态 HTML 响应?