Spring引导实体在嵌入对象中进行多对一映射

Sum*_*eet 5 java spring spring-data-jpa spring-boot

我正在构建一个简单的 Spring Boot 博客应用程序。这个应用程序有两个实体用户和帖子。user表保存用户数据,主键为Id,post表保存内容信息,外键为“postedBy”,用户信息引用user表的id。一个用户可以有很多帖子。

基于此,我设计了如下所示的实体类。

在此处输入图片说明

@Entity
@Table
public class User {
    @Id
    @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid", strategy = "uuid")
    private String id;
    private String name;
    private String email;
}


@Entity
@Table
public class Post {
    @Id
    @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid", strategy = "uuid")
    private String id;
    private String title;
    @ManyToOne
    @JoinColumn(name = "id" , insertable = false,updatable = false)
    private User postedBy;
    private String content;
}
Run Code Online (Sandbox Code Playgroud)

由于用户可以有多个帖子,我有用户 @ManyToOne注释,该注释通过@JoinColumn映射到用户的 id

我正在使用 JpaRepository 接口,然后通过休息控制器公开。

但是当我发送正文以插入如下所示的帖子时

{
    "title":"The Graphql way of design",
    "postedBy":"402880ee73aa45570173aa462ea00001",
    "content":" The content of blog "
}
Run Code Online (Sandbox Code Playgroud)

它抛出以下错误

Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.graphql.blog.model.User` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('402880ee73aa45570173aa462ea00001'); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.graphql.blog.model.User` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('402880ee73aa45570173aa462ea00001')
 at [Source: (PushbackInputStream); line: 3, column: 13] (through reference chain: com.graphql.blog.model.Post["postedBy"])]
Run Code Online (Sandbox Code Playgroud)

我期待postedBy 列将存储“402880ee73aa45570173aa462ea00001”,因为用户已经存在,作为响应,它会发送用户详细信息,自动获取该帖子的用户详细信息。

Ekl*_*vya 3

您收到错误是因为字符串字段无法反序列化为 的对象User

我期望 postsBy 列将存储“402880ee73aa45570173aa462ea00001”,因为用户已经存在,并且作为响应,它将发送用户详细信息,自动获取该帖子的用户详细信息。

不,Spring 不能自动执行此操作。为此,首先使用 json 正确反序列化 id,如下所示。

{
    "title":"The Graphql way of design",
    "postedBy":{
                  "id": "402880ee73aa45570173aa462ea00001"
               },
    "content":" The content of blog "
}
Run Code Online (Sandbox Code Playgroud)

然后先按Userid 获取并设置在 中Post,例如:

Optional<User> user = userRepository.findById(post.getPostedBy.getId());
post.setUser(user.get());
Run Code Online (Sandbox Code Playgroud)

并用于@JoinColumn要在帖子表中为用户存储外键的字段。

@ManyToOne
@JoinColumn(name = "postedBy")
private User postedBy;
Run Code Online (Sandbox Code Playgroud)