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