Using RowMapper and JdbcTemplate got NullPointerException
I have two entities - user and accessgroup. When getting user entity from MySQL database using RowMapper in JdbcTemplate I have NullPointerException. When not using setter for accessgroup in UserRowMapper I dont have NPE but have null in AccessGroup accessGroup.
Table
CREATE TABLE `users` ( `USER_ID` int(11) NOT NULL AUTO_INCREMENT, `USER_EMAIL` varchar(255) DEFAULT NULL, `USER_NAME` varchar(255) DEFAULT NULL, `USER_PWD` varchar(255) DEFAULT NULL, `ACCESSGROUP_GROUP_ID` int(11) DEFAULT NULL, PRIMARY KEY (`USER_ID`), KEY `FK_users_ACCESSGROUP_GROUP_ID` (`ACCESSGROUP_GROUP_ID`), CONSTRAINT `FK_users_ACCESSGROUP_GROUP_ID` FOREIGN KEY (`ACCESSGROUP_GROUP_ID`) REFERENCES `access_group` (`GROUP_ID`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
CREATE TABLE `access_group` ( `GROUP_ID` int(11) NOT NULL AUTO_INCREMENT, `GROUP_NAME` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`GROUP_ID`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
Entities
@Entity @Table(name = "users") public class User implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Basic(optional = false) @Column(name = "USER_ID") private Integer userId; @Column(name = "USER_EMAIL") private String userEmail; @Column(name = "USER_NAME") private String userName; @Column(name = "USER_PWD") private String userPwd; @JoinColumn(name = "ACCESSGROUP_GROUP_ID", referencedColumnName = "GROUP_ID") @ManyToOne private AccessGroup accessGroup;
@Entity @Table(name = "access_group") public class AccessGroup implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Basic(optional = false) @Column(name = "GROUP_ID") private Integer groupId; @Basic(optional = false) @Column(name = "GROUP_NAME") private String groupName; @OneToMany(mappedBy = "accessGroup") private Set users;
Dao
@Repository("userDao") public class UserDaoImpl implements IUserDao { @Autowired private JdbcTemplate jdbcTemplate; @Value("${sql.user.get.email.pwd}") private String getByEmailAndPwd; //sql.user.get.email.pwd=SELECT * FROM users WHERE user_email = ? AND user_pwd = ? @Transactional @Override public User getUserByEmailAndPwd(String email, String password) { return jdbcTemplate.queryForObject(getByEmailAndPwd, new Object[]{email, password}, new UserRowMapper()); }
@Repository("accessGroupDao") public class AccessGroupDaoImpl implements IAccessGroupDao { private JdbcTemplate jdbcTemplate; @Autowired public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @Value("${sql.accessgroup.get.id}") private String getAccessGroupById; //sql.accessgroup.get.id=SELECT * FROM access_group WHERE GROUP_ID = ? @Transactional @Override public AccessGroup getGroupById(int id) { return jdbcTemplate.queryForObject(getAccessGroupById, new Object[]{id}, new AccessGroupRowMapper()); }
RowMappers
@Component public class UserRowMapper implements RowMapper { private AccessGroupService accessGroupService; @Autowired public void setAccessGroupService(AccessGroupService accessGroupService) { this.accessGroupService = accessGroupService; } @Override public User mapRow(ResultSet resultSet, int i) throws SQLException { User user = new User(); user.setId(resultSet.getInt("USER_ID")); user.setEmail(resultSet.getString("USER_EMAIL")); user.setName(resultSet.getString("USER_NAME")); user.setpwd(resultSet.getString("USER_PWD")); //when adding here user.setAccessGroup(accessGroupService.getGroupById(resultSet.getInt("ACCESSGROUP_GROUP_ID"))); I have NPE return user; }
public class AccessGroupRowMapper implements RowMapper { @Override public AccessGroup mapRow(ResultSet resultSet, int i) throws SQLException { AccessGroup accessGroup = new AccessGroup(); accessGroup.setId(resultSet.getInt("GROUP_ID")); accessGroup.setName(resultSet.getString("GROUP_NAME")); return accessGroup; } }
1) Add the following property to your @Entity class 'User' & generate the getter & setter methods:
@Transient
private Integer userIdTransientField;
@Transient means the property will not be stored in the database
2) Modify RowMapper class:
Replace this line with the following :
user.setId(resultSet.getInt("USER_ID")); -> user.setUserIdTransientField(resultSet.getInt("USER_ID"));
3) When you refer to a 'User' object and you want to do a Update/Delete for jdbcTemplate or simply want to get the Id value then use the getUserIdTransientField method.
链接地址: http://www.djcxy.com/p/74424.html