我收到以下错误,这表明我没有在结果集上调用 next()
,但据我所知(即调试断点停止在 >rs.next()
并按预期填充)。
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [SELECT m.username, m.password, t.name as authority FROM members m JOIN administrator a ON a.member_id = m.member_id JOIN admin_type t ON t.admin_type_id = a.admin_type_id WHERE m.username = ?]; SQL state [24000]; error code [0]; ResultSet not positioned properly, perhaps you need to call next.; nested exception is org.postgresql.util.PSQLException: ResultSet not positioned properly, perhaps you need to call next.] with root cause
org.postgresql.util.PSQLException: ResultSet not positioned properly, perhaps you need to call next.
代码
@Autowired
NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
String sql = "SELECT m.username, m.password, t.name as authority FROM members m " +
"JOIN administrator a ON a.member_id = m.member_id " +
"JOIN admin_type t ON t.admin_type_id = a.admin_type_id " +
"WHERE m.username = :userName";
SqlParameterSource namedParameters = new MapSqlParameterSource().addValue("userName", userName);
List<User> users = namedParameterJdbcTemplate.query(sql, namedParameters, new UserDetailsRowMapper());
return users.get(0);
}
class UserDetailsRowMapper implements RowMapper<User> {
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
UserResultSetExtractor extractor = new UserResultSetExtractor();
return extractor.extractData(rs);
}
}
class UserResultSetExtractor implements ResultSetExtractor {
public User extractData(ResultSet rs) throws SQLException, DataAccessException {
Collection<SimpleGrantedAuthority> roles = new ArrayList<>();
while (rs.next()) {
String authority = rs.getString("authority");
roles.add( new SimpleGrantedAuthority(authority));
}
User user = new User(rs.getString("username"), rs.getString("password"), roles);
return user;
}
}
我不确定为什么会收到此错误。这可能是因为我的逻辑不正确,因为为结果集中的每一行调用了 extractData()
。
问题
我应该如何执行上述操作来填充与authorities
具有一对多关系的User
对象?
+-----------+ +---------------+ +---------------+
| Member | | administrator | | admin_type |
+-----------+ +---------------+ +---------------+
| member_id | | admin_id | | admin_type_id |
| username | | member_id | | name |
| password | | admin_type_id | +---------------+
+-----------+ +---------------+
SQL
SELECT m.username, m.password, t.name as authority FROM members m
JOIN administrator a ON a.member_id = m.member_id
JOIN admin_type t ON t.admin_type_id = a.admin_type_id
WHERE m.username = 'richardmarais';
结果
最佳答案
在您的代码中:
while (rs.next()) {
String authority = rs.getString("authority");
roles.add( new SimpleGrantedAuthority(authority));
}
User user = new User(rs.getString("username"), rs.getString("password"), roles);
return user;
您在 while 循环之外调用 rs.getString
,因此即使 rs.next()
没有为 true,也有可能。但更重要的是,当您跳出循环时,rs.next()
已返回 false,因此您的 get
将不再起作用。您没有提到在哪一行抛出异常,但我认为这是最可能的原因。
您应该在获取权限时随时填充用户信息,例如在第一行。但不要等到您已经处理完所有行。
例如这样:
public User extractData(ResultSet rs) throws SQLException, DataAccessException {
Collection<SimpleGrantedAuthority> roles = new ArrayList<>();
User user = null;
while (rs.next()) {
if (user == null) {
user = new User(rs.getString("username"), rs.getString("password"), roles);
}
String authority = rs.getString("authority");
roles.add( new SimpleGrantedAuthority(authority));
}
if (user == null) {
throw new MyException("User not found");
}
return user;
}
或者,只需使用 Hibernate 之类的框架来编写此类样板代码。
关于java - Spring jdbcTemplate OneToMany,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62523016/