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 中阅读更多相关信息)。
我有以下 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 中阅读更多相关信息)。