【问题标题】:Using RowMapper and JdbcTemplate got NullPointerException使用 RowMapper 和 JdbcTemplate 得到 NullPointerException
【发布时间】:2016-09-07 01:46:38
【问题描述】:

我有两个实体——用户和访问组。在 JdbcTemplate 中使用 RowMapper 从 MySQL 数据库获取用户实体时,出现 NullPointerException。在 UserRowMapper 中不使用 setter 访问组时,我没有 NPE,但在 AccessGroup accessGroup 中有 null。

表格

创建表`用户`( `USER_ID` int(11) NOT NULL AUTO_INCREMENT, `USER_EMAIL` varchar(255) 默认为 NULL, `USER_NAME` varchar(255) 默认为空, `USER_PWD` varchar(255) 默认为空, `ACCESSGROUP_GROUP_ID` int(11) 默认为 NULL, 主键(`USER_ID`), KEY `FK_users_ACCESSGROUP_GROUP_ID`(`ACCESSGROUP_GROUP_ID`), 约束`FK_users_ACCESSGROUP_GROUP_ID`外键(`ACCESSGROUP_GROUP_ID`)参考`access_group`(`GROUP_ID`) ) 引擎=InnoDB AUTO_INCREMENT=7 默认字符集=latin1; 创建表`access_group`( `GROUP_ID` int(11) NOT NULL AUTO_INCREMENT, `GROUP_NAME` varchar(255) NOT NULL DEFAULT '', 主键(`GROUP_ID`) ) 引擎=InnoDB AUTO_INCREMENT=2 默认字符集=latin1;

实体

@实体 @Table(name = "用户") 公共类用户实现可序列化{ @ID @GeneratedValue(策略 = GenerationType.IDENTITY) @基本(可选=假) @Column(name = "USER_ID") 私有整数用户 ID; @Column(name = "USER_EMAIL") 私人字符串用户邮箱; @Column(name = "USER_NAME") 私人字符串用户名; @Column(name = "USER_PWD") 私人字符串用户密码; @JoinColumn(name = "ACCESSGROUP_GROUP_ID", referencedColumnName = "GROUP_ID") @ManyToOne 私有访问组访问组; @实体 @Table(name = "access_group") 公共类AccessGroup实现可序列化{ @ID @GeneratedValue(策略 = GenerationType.IDENTITY) @基本(可选=假) @Column(name = "GROUP_ID") 私有整数组 ID; @基本(可选=假) @Column(name = "GROUP_NAME") 私有字符串组名; @OneToMany(mappedBy = "accessGroup") 私人集用户;

@Repository("userDao") 公共类 UserDaoImpl 实现 IUserDao { @自动连线 私有 JdbcTemplate jdbcTemplate; @Value("${sql.user.get.email.pwd}") 私人字符串 getByEmailAndPwd; //sql.user.get.email.pwd=SELECT * FROM users WHERE user_email = ?和 user_pwd = ? @Transactional @覆盖 公共用户getUserByEmailAndPwd(字符串电子邮件,字符串密码){ return jdbcTemplate.queryForObject(getByEmailAndPwd, new Object[]{email, password}, new UserRowMapper()); } @Repository("accessGroupDao") 公共类 AccessGroupDaoImpl 实现 IAccessGroupDao { 私有 JdbcTemplate jdbcTemplate; @自动连线 公共无效 setJdbcTemplate(JdbcTemplate jdbcTemplate){ this.jdbcTemplate = jdbcTemplate; } @Value("${sql.accessgroup.get.id}") 私有字符串 getAccessGroupById; //sql.accessgroup.get.id=SELECT * FROM access_group WHERE GROUP_ID = ? @Transactional @覆盖 公共访问组 getGroupById(int id) { return jdbcTemplate.queryForObject(getAccessGroupById, new Object[]{id}, new AccessGroupRowMapper()); }

行映射器

@零件 公共类 UserRowMapper 实现 RowMapper { 私有访问组服务访问组服务; @自动连线 公共无效 setAccessGroupService(AccessGroupService accessGroupService) { this.accessGroupService = accessGroupService; } @覆盖 公共用户 mapRow(ResultSet resultSet, int i) 抛出 SQLException { 用户用户 = 新用户(); user.setId(resultSet.getInt("USER_ID")); user.setEmail(resultSet.getString("USER_EMAIL")); user.setName(resultSet.getString("USER_NAME")); user.setpwd(resultSet.getString("USER_PWD")); //这里添加时 user.setAccessGroup(accessGroupService.getGroupById(resultSet.getInt("ACCESSGROUP_GROUP_ID")));我有 NPE 返回用户; } 公共类 AccessGroupRowMapper 实现 RowMapper { @覆盖 公共 AccessGroup mapRow(ResultSet resultSet, int i) 抛出 SQLException { 访问组访问组 = 新访问组(); accessGroup.setId(resultSet.getInt("GROUP_ID")); accessGroup.setName(resultSet.getString("GROUP_NAME")); 返回访问组; } }

【问题讨论】:

  • 让我们开始:你知道AccessGroupService accessGroupService是否被正确注入了吗?你能“检查”resultSet.getInt("ACCESSGROUP_GROUP_ID")吗?
  • 很明显它将是null... 您正在自己创建一个实例,并希望 Spring 向其中注入一些东西。不被 Spring 管理的 bean 实例将不会被注入。为什么你用 JPA 注解来注解你的类却使用 JDBC?

标签: java mysql spring spring-data jdbctemplate


【解决方案1】:

1) 将以下属性添加到您的 @Entity 类“用户”并生成 getter 和 setter 方法:

@Transient
private Integer userIdTransientField; 

@Transient 表示该属性不会存储在数据库中

2) 修改 RowMapper 类:

将此行替换为以下内容:

user.setId(resultSet.getInt("USER_ID")); -> user.setUserIdTransientField(resultSet.getInt("USER_ID"));

3) 当您引用“用户”对象并且想要对 jdbcTemplate 执行更新/删除或只是想获取 Id 值时,请使用 getUserIdTransientField 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-15
    • 2020-10-30
    • 2021-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-14
    相关资源
    最近更新 更多