Java Spring JPA关联实体创建相同的记录

Java Spring JPA关联实体创建相同的记录,java,json,spring,jpa,Java,Json,Spring,Jpa,我正在设置弹簧靴应用程序 尝试创建“添加用户菜单”,每次我发布JSON数据时,如以下示例所示: MySQL总是在role\u表中创建新的管理记录 我的目的是只在角色表中为用户表中的多个用户创建一条管理记录(一对一) 到目前为止,我已经尝试修改了几个SpringJPA注释,它们是不同类型的获取、关联和配置 到目前为止,我的MySql数据库表上的结果如下: role_table. user_table id. role. id username role_id 1 Ad

我正在设置弹簧靴应用程序 尝试创建“添加用户菜单”,每次我发布JSON数据时,如以下示例所示:

MySQL总是在
role\u表中创建新的管理记录

我的目的是只在
角色表
中为
用户表
中的多个用户创建一条管理记录(一对一)

到目前为止,我已经尝试修改了几个SpringJPA注释,它们是不同类型的获取、关联和配置

到目前为止,我的MySql数据库表上的结果如下:

role_table.    user_table
id.   role.    id    username  role_id
1    Admin      1    Tony      1
2.   User       2.   Buddy.    2
3.   Guest.     3.   Liaska.   3
4.   Admin      4.   Roy.      5
5.   Admin.     5.   Subrey.   4
6.   User.      6.   Alhanus.  7
7.   Guest      7.   Rsidi.    6
role_table.    user_table
id.   role.    id    username  role_id
1    Admin      1    Tony      1
2.   User       2.   Buddy.    2
3.   Guest.     3.   Liaska.   3
                4.   Roy.      1
                5.   Subrey.   3
                6.   Alhanus.  1
                7.   Rsidi.    1
public class Role implements Serializable{


@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name="id", length=8, unique = true)
private int id;

@Column(name = "role",nullable = false, unique = false)
private String role;

@OneToMany(mappedBy="role", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@Fetch(value = FetchMode.SUBSELECT)
private List<User> user = new ArrayList<User>();}
public class User implements Serializable{

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name="user_id", length=8, unique = true)
private int user_id;

@Column(name = "username", nullable = false, unique = true)
private String username;

@Column(name = "password", nullable = false, unique = true)
private String password;



@ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private Role role;}
public class AdminController {

private static final Logger LOGGER = LoggerFactory.getLogger(AdminController.class);


@Autowired
private UserRepository userRepository;

 @Autowired
  private RoleRepository roleRepository;

 private Role role = new Role();

@Autowired
 private BCryptPasswordEncoder passwordEncoder;

@PreAuthorize("hasAnyRole('ADMIN')")
@PostMapping("/admin/add")
 public String addUserByAdmin(@RequestBody User user){

    String pwd = user.getPassword();

    String encryptedPwd = passwordEncoder.encode(pwd);

    user.setPassword(encryptedPwd);



    if(userRepository.findByUsername(user.getUsername())==null){

        userRepository.save(user);

    } else {

         return "user already exist
    }
    return "user added successfully ... ";


}
我希望MySql表中的结果如下:

role_table.    user_table
id.   role.    id    username  role_id
1    Admin      1    Tony      1
2.   User       2.   Buddy.    2
3.   Guest.     3.   Liaska.   3
4.   Admin      4.   Roy.      5
5.   Admin.     5.   Subrey.   4
6.   User.      6.   Alhanus.  7
7.   Guest      7.   Rsidi.    6
role_table.    user_table
id.   role.    id    username  role_id
1    Admin      1    Tony      1
2.   User       2.   Buddy.    2
3.   Guest.     3.   Liaska.   3
                4.   Roy.      1
                5.   Subrey.   3
                6.   Alhanus.  1
                7.   Rsidi.    1
public class Role implements Serializable{


@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name="id", length=8, unique = true)
private int id;

@Column(name = "role",nullable = false, unique = false)
private String role;

@OneToMany(mappedBy="role", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@Fetch(value = FetchMode.SUBSELECT)
private List<User> user = new ArrayList<User>();}
public class User implements Serializable{

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name="user_id", length=8, unique = true)
private int user_id;

@Column(name = "username", nullable = false, unique = true)
private String username;

@Column(name = "password", nullable = false, unique = true)
private String password;



@ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private Role role;}
public class AdminController {

private static final Logger LOGGER = LoggerFactory.getLogger(AdminController.class);


@Autowired
private UserRepository userRepository;

 @Autowired
  private RoleRepository roleRepository;

 private Role role = new Role();

@Autowired
 private BCryptPasswordEncoder passwordEncoder;

@PreAuthorize("hasAnyRole('ADMIN')")
@PostMapping("/admin/add")
 public String addUserByAdmin(@RequestBody User user){

    String pwd = user.getPassword();

    String encryptedPwd = passwordEncoder.encode(pwd);

    user.setPassword(encryptedPwd);



    if(userRepository.findByUsername(user.getUsername())==null){

        userRepository.save(user);

    } else {

         return "user already exist
    }
    return "user added successfully ... ";


}
谢谢大家

像这样的角色类:

role_table.    user_table
id.   role.    id    username  role_id
1    Admin      1    Tony      1
2.   User       2.   Buddy.    2
3.   Guest.     3.   Liaska.   3
4.   Admin      4.   Roy.      5
5.   Admin.     5.   Subrey.   4
6.   User.      6.   Alhanus.  7
7.   Guest      7.   Rsidi.    6
role_table.    user_table
id.   role.    id    username  role_id
1    Admin      1    Tony      1
2.   User       2.   Buddy.    2
3.   Guest.     3.   Liaska.   3
                4.   Roy.      1
                5.   Subrey.   3
                6.   Alhanus.  1
                7.   Rsidi.    1
public class Role implements Serializable{


@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name="id", length=8, unique = true)
private int id;

@Column(name = "role",nullable = false, unique = false)
private String role;

@OneToMany(mappedBy="role", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@Fetch(value = FetchMode.SUBSELECT)
private List<User> user = new ArrayList<User>();}
public class User implements Serializable{

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name="user_id", length=8, unique = true)
private int user_id;

@Column(name = "username", nullable = false, unique = true)
private String username;

@Column(name = "password", nullable = false, unique = true)
private String password;



@ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private Role role;}
public class AdminController {

private static final Logger LOGGER = LoggerFactory.getLogger(AdminController.class);


@Autowired
private UserRepository userRepository;

 @Autowired
  private RoleRepository roleRepository;

 private Role role = new Role();

@Autowired
 private BCryptPasswordEncoder passwordEncoder;

@PreAuthorize("hasAnyRole('ADMIN')")
@PostMapping("/admin/add")
 public String addUserByAdmin(@RequestBody User user){

    String pwd = user.getPassword();

    String encryptedPwd = passwordEncoder.encode(pwd);

    user.setPassword(encryptedPwd);



    if(userRepository.findByUsername(user.getUsername())==null){

        userRepository.save(user);

    } else {

         return "user already exist
    }
    return "user added successfully ... ";


}
AdminController类,如下所示:

role_table.    user_table
id.   role.    id    username  role_id
1    Admin      1    Tony      1
2.   User       2.   Buddy.    2
3.   Guest.     3.   Liaska.   3
4.   Admin      4.   Roy.      5
5.   Admin.     5.   Subrey.   4
6.   User.      6.   Alhanus.  7
7.   Guest      7.   Rsidi.    6
role_table.    user_table
id.   role.    id    username  role_id
1    Admin      1    Tony      1
2.   User       2.   Buddy.    2
3.   Guest.     3.   Liaska.   3
                4.   Roy.      1
                5.   Subrey.   3
                6.   Alhanus.  1
                7.   Rsidi.    1
public class Role implements Serializable{


@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name="id", length=8, unique = true)
private int id;

@Column(name = "role",nullable = false, unique = false)
private String role;

@OneToMany(mappedBy="role", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@Fetch(value = FetchMode.SUBSELECT)
private List<User> user = new ArrayList<User>();}
public class User implements Serializable{

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name="user_id", length=8, unique = true)
private int user_id;

@Column(name = "username", nullable = false, unique = true)
private String username;

@Column(name = "password", nullable = false, unique = true)
private String password;



@ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private Role role;}
public class AdminController {

private static final Logger LOGGER = LoggerFactory.getLogger(AdminController.class);


@Autowired
private UserRepository userRepository;

 @Autowired
  private RoleRepository roleRepository;

 private Role role = new Role();

@Autowired
 private BCryptPasswordEncoder passwordEncoder;

@PreAuthorize("hasAnyRole('ADMIN')")
@PostMapping("/admin/add")
 public String addUserByAdmin(@RequestBody User user){

    String pwd = user.getPassword();

    String encryptedPwd = passwordEncoder.encode(pwd);

    user.setPassword(encryptedPwd);



    if(userRepository.findByUsername(user.getUsername())==null){

        userRepository.save(user);

    } else {

         return "user already exist
    }
    return "user added successfully ... ";


}

问题在于初始化
角色
对象的持久性。在这里,您将获得JSON中的用户对象,如下所示:

 {"username": "Frantu", "password": "Pshycho8k8ss", "role" : {"role":"ADMIN"} }
没有为角色实体初始化id字段

因此,您的用户对象将是

User {id=0, username = Frantu, password= Pshycho8k8ss , role = {id=0, role=ADMIN }
您没有在此处传递
role.id
,因此JPA将为每个新请求创建一个带有新主键的新记录

要解决此问题,首先,使用
role
属性从数据库(如果存在)获取
role
,并将其设置为用户对象

Role dbRole = roleRepository.findByRole(user.getRole().getRole());
if(dbRole!=null){
     user.setRole(dbRole);
}

userRepository.save(user);

您如何保存角色。在AdminController中,我只能看到创建了一个新的角色对象。它在哪里与用户链接?你能添加代码的这一部分吗?我只是简单地用名为postman的应用程序发布JSON对象,spring处理一切,我不创建链接用户,spring引导自动处理,我发布的JSON数据看起来像这样“用户名”:“Frantu”,“password”:“Pshycho8k8ss”,“role”:{“role”:“ADMIN”},因为您只是作为管理员传递角色,而没有主键。它被视为一个新记录,您在DB中有多个角色。我现在就知道了。。。谢谢大家。将cascadeType.ALL更改为cascadeType.MERGE工作…使用JSON数据,如用户{id=0,用户名=Frantu,密码=Pshycho8k8ss,角色={id=0,角色=ADMIN}用户{id=0,用户名=Frantu,密码=Pshycho8k8ss,角色={id=0,角色=ADMIN}对我来说真的工作…将cascadeType.ALL更改为cascadeType.MERGE…谢谢你的帮助。