【问题标题】:Null Foreign Key (Springboot, Hibernate, Postman)空外键(Springboot、Hibernate、Postman)
【发布时间】:2020-11-25 13:51:47
【问题描述】:

我正在使用带有 Hibernate 的 Springboot,我想使用 POST 请求将新的“帖子”保存到我的数据库。我想强调的一件事是我正在使用依赖项“spring-boot-starter-data-rest”。

数据库架构(MySQL):

班级用户:

@Entity
@Table(name="user")
public class User implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id", nullable = false)
    public int id;

    @OneToMany(mappedBy = "user_id_fk")
    public Set<Post> posts;

    @Column(name="email")
    private String email;

    @Column(name="username")
    private String username;

    @Column(name="password")
    private String password;

    @Column(name="first_name")
    private String firstName;

    @Column(name="last_name")
    private String lastName;

    @Column(name="create_time")
    protected Date createTime;

    @Column(name="type")
    private String accountType;

    public User() {
        this.createTime = new java.util.Date();
    }

    public User(String email, String username, String password, String firstName, String lastName, Date createTime, String accountType) {
        this.email = email;
        this.username = username;
        this.password = password;
        this.firstName = firstName;
        this.lastName = lastName;
        this.createTime = createTime;
        this.accountType = accountType;
        this.createTime = new java.util.Date();
    }

    public User(int id, String email, String username, String password, String firstName, String lastName, Date createTime, String accountType) {
        this.id = id;
        this.email = email;
        this.username = username;
        this.password = password;
        this.firstName = firstName;
        this.lastName = lastName;
        this.createTime = createTime;
        this.accountType = accountType;
        this.createTime = new java.util.Date();
    }

加上Getters & Setters & toString()。

班级帖子:

@Entity
@Table(name="post")
public class Post implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    public int id;

    @ManyToOne(optional = false)
    @JoinColumn(name = "user_id_fk", nullable = false)
    public User user_id_fk;

    @Column(name="comment")
    private String comment;

    @Column(name="likes")
    private int likes;

    @Column(name="dislike")
    private int dislike;

    @Column(name="create_time")
    protected Date createTime;

    public Post() {
        this.createTime = new java.util.Date();
    }

    public Post(String comment, int likes, int dislike, User user_id_fk) {
        this.user_id_fk = user_id_fk;
        this.comment = comment;
        this.likes = likes;
        this.dislike = dislike;
        this.createTime = new java.util.Date();
    }

    public Post(int id, User user_id_fk, String comment, int likes, int dislike) {
        this.id = id;
        this.user_id_fk = user_id_fk;
        this.comment = comment;
        this.likes = likes;
        this.dislike = dislike;
        this.createTime = new java.util.Date();
    }

加上Getters & Setters & toString()。

发布请求(我正在使用 Postman 发送请求):

{
"comment" : "This is a comment",
"likes" : 123,
"dislike" : 1,
"user_id_fk" :
[
    {
        "id" : 1
    }
]
}

在 "user_id_fk" 的请求中,我尝试使用 [ {"id" : 1 } ] 和 { "id" : 1 } 但结果是一样的。

问题:

当我从我的控制器执行完全相同的代码时,一切正常的情况除外。请记住,我正在使用依赖项“spring-boot-starter-data-rest”。 此外,当我在没有“optional = false”“nullable = false” 的情况下执行代码时,会将数据插入数据库但“user_id_fk”为空:(。

我得到的错误:

not-null property references a null or transient value : com.citizen.citizen.entity.Post.user_id_fk; 
nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value : com.citizen.citizen.entity.Post.user_id_fk]

这意味着外键("user_id_fk") 为空但不应为空。 任何帮助将不胜感激。

【问题讨论】:

  • 您为什么将您的用户命名为 user_id_fk?它被标识为连接列名称,但为什么还要将引用的实体命名为呢?我之前曾让 spring 对这样的命名冲突感到困惑。
  • 我尝试使用另一个名称,例如“用户”,但我仍然遇到同样的问题。
  • id 为 1 的用户是否已经存在,或者您是否也在尝试创建它?
  • 是的,ID 为 1 的用户存在。实际上我在数据库中有几个用户。我还尝试发送 ID 为 1 的用户的所有信息,但我又遇到了同样的错误。

标签: spring-boot postman spring-data-rest


【解决方案1】:

我只是删除了依赖项“spring-boot-starter-data-rest”,然后通过创建自定义休息解决了这个问题,一切正常。亲吻!

【讨论】:

  • 我也遇到了同样的问题,你是怎么做到的?
【解决方案2】:

根据this 文章,您应该使user_id_fk 可以为空,然后:

  1. 发送 POST 创建用户
  2. 发送第二个 POST 以创建帖子
  3. 发送 PUT 以创建两者之间的关系。

This 文章声明相同。 而documentation 只提到通过关联链接处理关联。

【讨论】:

  • 感谢您的回复。我明白你在说什么,但发送第二个请求也不适合我的用例。如果可能的话,我想在一个 POST 请求中进行。
  • 我添加了更多链接,但是根据我对 Spring Data REST 的了解,您想要的是不可能的。您需要为此编写自定义控制器。
  • 每个 cmets,用户已经存在,所以这应该可以通过单个查询来实现。
  • 即使用户存在,您仍然需要两个查询:一个用于创建帖子,另一个用于将帖子分配给用户。除非我误解了什么?
  • 是的,因为我可以理解您是正确的文档。无论如何,这种解决方法对我不起作用,我在不使用依赖项“spring-boot-starter-data-rest”的情况下完成了所有 REST 自定义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-26
  • 1970-01-01
  • 1970-01-01
  • 2017-12-28
  • 2017-03-14
  • 1970-01-01
  • 2014-08-30
相关资源
最近更新 更多