Spring Boot双H2数据库问题:我的数据表去哪了?
嘿,我碰到过好几个类似的场景——H2数据库看起来一切正常,表和数据都能在控制台看到,但登录就是失败。结合你描述的情况,大概率是认证逻辑和数据库数据不匹配,咱们一步步排查:
1. 优先检查密码加密一致性
这是最常见的坑!如果你的Spring Security配置了密码加密(默认就会要求加密),但你预填充到H2的密码是明文,那系统会把你输入的密码加密后和数据库里的明文比对,自然不匹配。
举个例子:如果你的
data.sql里是这样写的:INSERT INTO users (username, password) VALUES ('admin', 'admin');但你的Security配置里用了
BCryptPasswordEncoder,那肯定会报BadCredentialsException。解决办法:
- 先生成加密后的密码:写个简单的测试类生成BCrypt加密串:
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; public class PasswordGen { public static void main(String[] args) { System.out.println(new BCryptPasswordEncoder().encode("admin")); } } - 把输出的加密串替换到
data.sql的password字段里:INSERT INTO users (username, password, enabled) VALUES ('admin', '$2a$10$xxxxxx...', true); - 确保你的Security配置里注入了对应的PasswordEncoder:
@Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
- 先生成加密后的密码:写个简单的测试类生成BCrypt加密串:
2. 验证用户查询逻辑是否正确
如果你自定义了UserDetailsService或者用了JDBC认证,要确认查询语句是否能正确取到用户数据:
- 手动在H2控制台执行你的查询语句,比如:
看看返回的结果里,password字段是不是你预期的值,enabled是不是SELECT username, password, enabled FROM users WHERE username = 'admin';true(如果有这个字段的话)。 - 如果用的是
JdbcUserDetailsManager,检查usersByUsernameQuery和authoritiesByUsernameQuery的SQL是否和你的表结构匹配,比如字段名是不是写错了(比如把user_name写成了username)。
3. 确认用户状态是否启用
很多时候用户表会有enabled字段,如果预填充数据时这个字段设为false,Spring Security会直接拒绝登录请求,抛出DisabledException。
- 检查
data.sql里的INSERT语句,确保enabled字段值为true,如果表结构里这个字段默认是false,一定要显式设置。
4. 查看完整的错误日志
你贴的日志只到开头,完整的异常信息是关键!比如:
BadCredentialsException:密码比对失败(对应上面的加密问题)UsernameNotFoundException:系统找不到该用户(对应查询逻辑问题)DisabledException:用户被禁用(对应enabled字段问题)
把完整的异常栈信息找出来,能直接锁定问题根源。
5. 确认数据库初始化顺序
虽然你说能看到数据,但还是要确认下schema.sql和data.sql的执行顺序是否正确:
- 检查
application.properties里的spring.sql.init.mode是否设为always(确保每次启动都初始化) - 确认
schema.sql是先建表,data.sql再插入数据,避免数据插入到不存在的表中(虽然H2控制台能看到数据,这个可能性低,但可以排除)
内容的提问来源于stack exchange,提问作者rray
相关产品推荐
相关产品推荐

