空外键(Springboot、Hibernate、Postman)
Posted
技术标签:
【中文标题】空外键(Springboot、Hibernate、Postman)【英文标题】:Null Foreign Key (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 的用户的所有信息,但我又遇到了同样的错误。 【参考方案1】:我只是删除了依赖项“spring-boot-starter-data-rest”,然后通过创建自定义休息解决了这个问题,一切正常。亲吻!
【讨论】:
我也遇到了同样的问题,你是怎么做到的?【参考方案2】:根据this 文章,您应该使user_id_fk
可以为空,然后:
-
发送 POST 创建用户
发送第二个 POST 以创建帖子
发送 PUT 以创建两者之间的关系。
This 文章声明相同。 而documentation 只提到通过关联链接处理关联。
【讨论】:
感谢您的回复。我明白你在说什么,但发送第二个请求也不适合我的用例。如果可能的话,我想在一个 POST 请求中进行。 我添加了更多链接,但是根据我对 Spring Data REST 的了解,您想要的是不可能的。您需要为此编写自定义控制器。 每个 cmets,用户已经存在,所以这应该可以通过单个查询来实现。 即使用户存在,您仍然需要两个查询:一个用于创建帖子,另一个用于将帖子分配给用户。除非我误解了什么? 是的,因为我可以理解您是正确的文档。无论如何,这种解决方法对我不起作用,我在不使用依赖项“spring-boot-starter-data-rest”的情况下完成了所有 REST 自定义。以上是关于空外键(Springboot、Hibernate、Postman)的主要内容,如果未能解决你的问题,请参考以下文章