Icce___
2019-09-24 16:25
采纳率: 36.4%
浏览 580
已采纳

springboot JPA保存报错

用户类

@Entity
@SecondaryTable(name="sys_user_extend")
@GenericGenerator(name = "jpa-uuid", strategy = "uuid")
public class SysUser implements UserDetails {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public SysUser() {
    }

    public SysUser(String loginName, String password) {
        super();
        this.loginName = loginName;
        this.password = password;
    }

    @Id
    @GeneratedValue(generator = "jpa-uuid")
    private String id;
    @Column(unique=true ,nullable = false)
    private String loginName;
    @Column(nullable = false)
    private String password;
    @Column(unique=true ,nullable = false)
    private String name;
    @Column(unique=true)
    private String email;
    @Column(unique=true)
    private String phone;
    @Column
    private String remark;
    @Column
    private String lastLoginTime;
    @Column(nullable = false)
    private String isActive = "true";
    @Column(table="sys_user_extend")
    private String level;
    @Column(table="sys_user_extend")
    private String currentExperience;
    @Column(table="sys_user_extend")
    private String totalExperience;
    @ManyToMany(cascade = { CascadeType.REFRESH }, fetch = FetchType.EAGER)
    private List<SysRole> roles;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> authorities = new ArrayList<>();
        List<SysRole> roles = this.getRoles();
        for (SysRole role : roles) {
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }
        return authorities;
    }

//省略get、set方法
}
public interface SysUserRepository extends JpaRepository<SysUser, Long> {
    SysUser findByLoginName(String loginname);

    SysUser findByPhone(String phone);

    SysUser findByEmail(String email);
}

controller层的添加方法

    //添加
    @ResponseBody
    @RequestMapping(value="/user",method=RequestMethod.POST)
    public Object post(@RequestBody SysUser user){
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encodedPassword  = passwordEncoder.encode(user.getPassword());
        user.setPassword(encodedPassword);
        userserivce.saveUser(user);
        return user;
    }

数据库用户表
数据库用户扩展信息表

报错信息:

org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: (was java.lang.NullPointerException); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.sakuraSmiles.alpha.security.model.SysUser[\"authorities\"])"

测试json

{"loginName":"test123","name":"测试","password":"123456","level":"5"}

项目使用了spring security,通过postman模拟请求,debug跟了下发现controller层的user是能拿到我传的对象的,但是里面也没有authorities字段。网上找了好久也没看到有跟我这个类似的,请问有人碰到过相似的问题吗?或者有大佬帮忙看一看吗?

感谢1楼和3楼大牛的解答帮助,十分感谢两位的帮助。分想要两位都给的,没办法只能选择一个采纳,就先给了1楼。问题已经解决了,定位到就是如3楼大牛所说,因为实现UserDetails 接口会有getAuthorities方法,在进行序列化时发现有带getXX开始的方法会自动去找XX的属性,
但是发现并没这个属性,所以报错。网上搜索了一下jpa有没有能够让系统能够忽视这个get方法的注释,在getAuthorities方法上面添加了@JsonIgnore就执行save不会报错了,目前没看出对于其他地方有没有影响。

    @Override
    @JsonIgnore
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> authorities = new ArrayList<>();
        List<SysRole> roles = this.roles;
        for (SysRole role : roles) {
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }
        return authorities;
    }

图片说明

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • _鹿慕溪水 2019-09-24 16:30
    已采纳

    看一下你的user类有没有实现序列化接口

    点赞 评论
  • dabocaiqq 2019-09-24 16:40

    默认的AUTO,这种方式如果数据库中不存在这张表的时候,用它来指定自增方式没有问题,但是如果数据库中已经存在这张表并设计了自动方式,那么插入数据的时候就会报错。

    https://blog.csdn.net/wxr15732623310/article/details/79608512

    点赞 评论
  • infoworld 2019-09-24 16:42

    我说说我的看法,你的SysUser 类有这个getAuthorities方法, 在进行序列化时发现有带getXX开始的方法会自动去找XX的属性,
    但是发现并没这个属性,所以报错。所以你的方法不应该用get开头,或者声明一个Annotation不要理这个方法。

    点赞 评论

相关推荐 更多相似问题