我似乎不知道如何通过JSON添加具有外键的实体。
我有一个用户模型和一个帖子模型。一个用户可以在一个网站上发表不同的帖子。
这是一个多对一的关系。一个用户可以有多个帖子,而一个帖子只能有一个用户(发帖者)。帖子作为外键代表发帖用户的ID。
这是用户模型:
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Table(name = "user")
public class User {
//ID
@Id
@SequenceGenerator(
name = "user_sequence",
sequenceName = "user_sequence",
allocationSize = 1
)
@GeneratedValue(
strategy = GenerationType.IDENTITY,
generator = "user_generator"
)
@Column(name = "id",nullable = false)
private int id;
private String username;
private String password;
private String email;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd")
@Column(name = "creation_date")
private Date creationDate;
//RELATIONSHIP
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<Post> posts = new ArrayList<>();
/* =========== GETTERS AND SETTERS ===========*/
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public List<Post> getPosts() {
return posts;
}
public void setPosts(List<Post> posts) {
this.posts = posts;
}
}
这是Post模型:
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Table(name = "post")
public class Post {
//ID
@Id
@SequenceGenerator(
name = "post_sequence",
sequenceName = "post_sequence",
allocationSize = 1
)
@GeneratedValue(
strategy = GenerationType.IDENTITY,
generator = "post_generator"
)
@Column(name = "id", nullable = false)
private int id;
@Column(name = "post_content")
private String postContent;
private String title;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd")
@Column(name = "creation_date")
private Date creationDate;
//RELATIONSHIP
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "user_id", referencedColumnName = "id")
private User user;
/* ======== GETTERS AND SETTERS ======== */
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPostContent() {
return postContent;
}
public void setPostContent(String postContent) {
this.postContent = postContent;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
这是postController:
@RestController
public class PostController {
@Autowired
private PostService postService;
@PostMapping("/savePost")
public Post getPost(@Validated @RequestBody Post post) {
return postService.savePost(post);
}
@GetMapping("getPost/{id}")
public Post getPost(@PathVariable int id) {
return postService.getPost(id);
}
@PutMapping("/deletePost/{id}")
public void deletePost(int id) {
postService.deletePost(id);
}
}
这是我在添加帖子时发送的JSON。Request to:地址:
{
"postContent": "some content",
"creationDate": "2022-07-31",
"title": "my title",
"user": 1
}
但是在postMan中我得到这个错误:
{
"timestamp": "2022-08-02T10:40:11.794+00:00",
"status": 400,
"error": "Bad Request",
"path": "/savePost"
}
在Spring我得到这个错误:JSON解析错误:无法构造x.model.User的示例(尽管至少存在一个创建者):没有int/Int-argument构造函数/工厂方法要从Number值(1)反序列化;
如果我在JSON中发送请求,其中我调用用户“user_id”或“uderId”,那么我可以发送请求,但随后外键变为空
{
"creationDate": "2022-07-31",
"postContent": "some content",
"title": "my title",
"user_id": 1
}
发送的内容:
{
"id": 2,
"postContent": "some content",
"title": "my title",
"creationDate": "2022-07-31",
"user": null
}
有人知道我做错了什么吗?
1条答案
按热度按时间xqkwcwgp1#
首先,您的API在
REST
concept. Here is a nice explanation方面不正确。您最好重新处理它以处理Post
实体:userId
参数添加到控制器的value
中,然后将其从模型中删除。Open session in View
问题。您必须:
fetch = FetchType.LAZY
添加到@OneToMany
和@ManyToOne
声明中;userId
属性添加到PostUpdateDTO
(如果允许更改帖子的所有者)在服务层,您可以:
POST
:通过userId
查找User
,验证是否存在该实体,如果不存在,则可能引发某个异常,或者创建并持久化一个新Post
实体:PUT
:通过userId
和id
找到一个Post
实体,验证它是否存在,并实现较好的逻辑。我不知道是否允许重新分配用户?如果允许,请先检查新用户是否存在。DELETE
,您可以在实体不存在的情况下引发异常,但许多情况下不会引发异常,并且不会对发送的成功响应采取任何措施我们使用传输对象的另一个原因。如果你让它保持原样,它将在序列化时导致无限循环:
post.user -> (post: user.posts) {post.user -> ...}
.当然,所有这些并不是解决这个问题的唯一方法,也没有回答关于
Java Persistance API
的所有问题,但这是我不久前在一个具体项目中采用的方法。Here is是Spring
团队制作的REST指南