child表没有Map到jpa中的onetomany关系中

yb3bgrhw  于 2021-07-16  发布在  Java
关注(0)|答案(2)|浏览(349)

我试图在用户和角色之间建立一对多关系。
一个用户可以有多个角色。
下面是用户类的代码

@Entity

public class User {

    @Id
    private int id;
    private String name;
    private String password;
    private String email;
    private String phoneNo;

    @OneToMany(
                targetEntity = Role.class,
                mappedBy = "user", 
                cascade = CascadeType.ALL, 
                fetch = FetchType.LAZY
              )

    private Set<Role> roles;        

    // Getters, setters and Constructor

角色类的代码

@Entity
public class Role {

    @Id
    @GeneratedValue
    private int roleId;
    private String role;  

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;       

    // Getters, setters and Constructor

   POST request on Postman is        

{
    "id":101,
    "name": "rahul",
    "password": "456",
    "email": "rahul@gmail.com",
    "phoneNo": "1234561234",
    "role": [{
        "role":"USER"
    }]
}

Code on Configuration part       

    @Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

     protected void configure(HttpSecurity http)throws Exception
     {
        http.csrf().disable();
     }

    @Bean
    public BCryptPasswordEncoder passwordEncoder()
    {
        return new BCryptPasswordEncoder();
    }
}         

Code On Controller part

@RestController
public class AdminController {

    @Autowired
    UserRepository userRepo;

    @Autowired
    BCryptPasswordEncoder encryptPassword;

    @PostMapping("/admin/add")
    public String addUserByAdmin(@RequestBody User user)
    {
        String pass = user.getPassword();
        String encrypt = encryptPassword.encode(pass);
        user.setPassword(encrypt);

        userRepo.save(user);
        return "User added Successfully";
    }
}

通过jpa与数据库的角色表连接

public interface RoleRepository extends JpaRepository<Role, Integer> {

}

通过jpa连接到数据库的用户表

public interface UserRepository extends JpaRepository<User,Integer>{

}

这里的问题是用户表Map正确,但角色表没有得到Map。

roleId    role    user_id         
NULL      NULL    NULL

我错在哪里?有人能帮我吗?

pkbketx9

pkbketx91#

在下面的控制器方法中,是否尝试调试传入的请求用户对象?
总之,我有以下几点:
首先,查看您的请求主体,您的角色字段被命名为 role 当你的用户对象有一个字段 roles 因此,我很肯定是这样 null 在处理过程中,由于字段名不匹配,因此不会在那里反序列化。尝试将请求正文更改为以下内容:

{
    "id":101,
    "name": "rahul",
    "password": "456",
    "email": "rahul@gmail.com",
    "phoneNo": "1234561234",
    "roles": [{
        "role":"USER"
    }]
}

第二,如果检查数据库,则角色将被持久化,而不是保留外键 user_id 为空。这是意料之中的。您对用户对象所做的级联只意味着(因为您使用cascadetype.all)保存用户对象后,保存操作也将级联到角色对象,但是jpa仍然需要知道关系,因此您必须为每个角色对象设置用户。因此,您可以将控制器方法更新为以下内容:

@PostMapping("/admin/add")
public String addUserByAdmin(@RequestBody User user)
{
  String pass = user.getPassword();
  String encrypt = encryptPassword.encode(pass);
  user.setPassword(encrypt);
  // JPA needs to know this relationship...
  user.getRoles().forEach(role -> role.setUser(user));
  userRepo.save(user);
  return "User added Successfully";
}

现在你可以试着看到你预期的行为现在应该发生了。
其他建议:
为什么我们要在用户请求中传递id字段?您只需将其从请求正文中删除,然后使用下面的命令自动生成ID,以避免在所有实体上出现唯一索引或主键冲突异常:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

也可以删除 targetEntity = Role.class 在Map上,因为它只用于泛型,对于您的情况,显然您没有将泛型用于set。更新角色Map的用户对象:

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<Role> roles;

最后,如果您可以将传入的有效负载 Package 到dto,那就更好了,因为您不想将您的实体/模型暴露给api,但我认为这只是针对您的测试环境。

2w2cym1i

2w2cym1i2#

使用时需要刷新对数据库的更改 save() ,请尝试以下操作:

userRepo.saveAndFlush(user);

相关问题