通过创建
User
和 Authority
类来实现身份验证,如下所示:
用户
package com.blog.blog.entity;
import jakarta.persistence.*;
@Entity
@Table(name = "authorities")
public class Authority {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
用户
package com.blog.blog.entity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.*;
import org.hibernate.annotations.CreationTimestamp;
import java.util.Set;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private int id;
private String name;
private String email;
@Column(name = "mobile_number")
private String mobileNumber;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String pwd;
@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
private String createdAt;
// @JsonIgnore
@OneToMany(mappedBy="user",fetch=FetchType.EAGER, cascade = CascadeType.ALL)
private Set<Authority> authorities;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMobileNumber() {
return mobileNumber;
}
public void setMobileNumber(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public Set<Authority> getAuthorities() {
return authorities;
}
public void setAuthorities(Set<Authority> authorities) {
this.authorities = authorities;
}
}
我的控制器保存
User
看起来像这样:
package com.blog.blog.controller;
// ...
@RestController
public class RegistrationController {
private final UserRepo userRepo;
public RegistrationController(UserRepo userRepo) {
this.userRepo = userRepo;
}
@PostMapping("/register")
public ResponseEntity<User> register(@RequestBody User userRequest){
User u = userRepo.save(userRequest);
return new ResponseEntity<>(u, HttpStatus.CREATED);
}
}
这是 JSON 有效负载:
{
"name": "aa",
"email": "[email protected]",
"mobileNumber": 1999,
"pwd": "password",
"authorities": [
{ "name": "ROLE_ADMIN"}
]
}
问题:
在数据库中填充
User
记录,但Authority
记录与User
记录不关联:
这就是它的样子:
当我检查日志时,我看到插入
Authority
记录时 user_id
指向 null
。
2024-02-04T12:00:57.803+05:30 TRACE 661939 --- [nio-8080-exec-1] org.hibernate.orm.jdbc.bind : binding parameter (1:INTEGER) <- [4]
2024-02-04T12:00:57.810+05:30 DEBUG 661939 --- [nio-8080-exec-1] org.hibernate.SQL : insert into authorities (name,user_id) values (?,?)
2024-02-04T12:00:57.810+05:30 TRACE 661939 --- [nio-8080-exec-1] org.hibernate.orm.jdbc.bind : binding parameter (1:VARCHAR) <- [ROLE_ADMIN]
2024-02-04T12:00:57.810+05:30 TRACE 661939 --- [nio-8080-exec-1] org.hibernate.orm.jdbc.bind : binding parameter (2:INTEGER) <- [null]
当您有双向
@OneToMany
关联时,关联双方都需要同步以确保数据一致性。这意味着子实体必须了解父实体才能设置正确的外键 (user_id
)。
register
方法应更改为以下内容:
public ResponseEntity<User> register(@RequestBody User userRequest){
userRequest.getAuthorities().forEach(i -> i.setUser(userRequest));
User u = userRepo.save(userRequest);
return new ResponseEntity<>(u, HttpStatus.CREATED);
}
通常,在父端定义两个实用方法,如下所示,自动同步子端。
public void addAuthority(Authority authority) {
authorities.add(authority);
authority.setUser(this);
}
public void removeAuthority(Authority authority) {
authorities.remove(authority);
authority.setUser(null);
}
@OneToMany
关系的最佳方式