JpaRepository 返回列表中第一项的子项,然后仅返回其余项的 id

JpaRepository returning child for the first item in the list and then only the id for the rest

我有以下 Post class:

@Entity
@Table(name = "posts")
@Getter
@Setter
@JsonIdentityInfo(      generator = ObjectIdGenerators.PropertyGenerator.class, 
                        property  = "id", 
                        scope     = Long.class)
public class Post {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String title;
    
    private String subtitle;
    
    private String content;
    
    private String img_url;
    
    @CreationTimestamp
    private Timestamp created_on;
    
    @UpdateTimestamp
    private Timestamp last_updated_on;
    
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "owner_id", nullable=false)
    @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
    private User creator;
    
}

以及扩展 JpaRepository 的以下存储库

@Repository
public interface PostRepository extends JpaRepository<Post, Long> {

    Optional<Post> findById(Long id);
    
    List<Post> findAll();
    
}

在以下控制器中返回 findAll() 的结果时,只有第一个创建者项目被完整发送,其余仅包含 id:

@GetMapping("/news")
    public List<Post> getNews() {
        return postRepository.findAll();
    }

这是 JSON 我得到的结果:

[
{"id":15,"title":"Title example #1","subtitle":"Subtitle example #1","content":"Lorem #1 ipsum dolor sit amet","img_url":null,"created_on":"2021-12-01T00:00:00.000+00:00","last_updated_on":"2021-12-01T00:00:00.000+00:00","creator":{"id":1,"username":"user-example","email":"blablabla@gmail.com","roles":[{"id":1,"name":"ROLE_USER"}]}}

,{"id":25,"title":"Title example #2","subtitle":"Subtitle example #2","content":"Lorem #2 ipsum dolor sit amet","img_url":null,"created_on":"2021-12-01T00:00:00.000+00:00","last_updated_on":"2021-12-01T00:00:00.000+00:00","creator":1}
]

为什么会这样?有没有一种方法可以为 JSON 数组中的每个元素获取整个子对象?

谢谢

编辑:添加了 User class

@Entity
@Table( name = "users", 
        uniqueConstraints = { 
            @UniqueConstraint(columnNames = "username"),
            @UniqueConstraint(columnNames = "email") 
        })
@DiscriminatorValue(value="USER")
public class User extends OwnerEntity {

    @NotBlank
    @NotNull
    @Size(max = 20)
    private String username;

    @NotBlank
    @NotNull
    @Size(max = 50)
    @Email
    private String email;

    @NotBlank
    @Size(max = 120)
    @JsonIgnore
    private String password;
    
    @CreationTimestamp
    private Timestamp created_on;
    
    @UpdateTimestamp
    private Timestamp last_updated_on;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable( name = "user_roles", 
                joinColumns = @JoinColumn(name = "user_id"), 
                inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> roles = new HashSet<>();

    @ManyToMany(fetch = FetchType.LAZY)
    private Set<Institution> institutions;
    
    @OneToMany(mappedBy="creator", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    protected Set<Post> posts;
    
    @ManyToMany(fetch = FetchType.LAZY)
    private Set<Institution> following;
}

编辑 2:添加了 OwnerEntity class

@Entity
@Table(name = "entities")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
@Getter
@Setter
@JsonIdentityInfo(      generator = ObjectIdGenerators.PropertyGenerator.class, 
                        property  = "id", 
                        scope     = Long.class)
public class OwnerEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Long id;
    
}

你的 OwnerEntity 还有 @JsonIdentityInfo。在它的 reference documentation 中我们可以读到以下内容:

Annotation used for indicating that values of annotated type or property should be serializing so that instances either contain additional object identifier (in addition actual object properties), or as a reference that consists of an object id that refers to a full serialization. In practice this is done by serializing the first instance as full object and object identity, and other references to the object as reference values.

这完美地解释了为什么您会得到这样的 JSON。如果您不想要这个,只需删除 @JsonIdentityInfo 但它可能会在序列化双向关系时修复无限递归(您可以在以下在线资源 https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion 中阅读更多相关信息)。