升级至Hibernate 5后出现H2数据库密码问题
我之前升级Hibernate时也碰到过一模一样的坑,结合Hibernate 5.x的特性和H2数据库的变化,主要有这几个可能的原因和对应的解决办法:
1. Hibernate 5.x对连接属性的处理更严格
在Hibernate 4.x里,如果你没显式配置H2的用户名和密码,它会默认用H2的sa用户名+空密码组合。但Hibernate 5.x开始对JPA规范的实现更严格,加上它依赖的H2版本大概率也升级了——新版H2不再默认允许无密码或者省略用户名的连接,必须显式指定。
解决办法:
直接在你的测试配置里补全用户名和密码:
- 如果是Spring Boot的
application-test.properties:spring.datasource.username=sa spring.datasource.password= - 如果是传统的
persistence.xml,在<persistence-unit>的<properties>里加:<property name="javax.persistence.jdbc.user" value="sa"/> <property name="javax.persistence.jdbc.password" value=""/>
2. Hibernate 5.x与旧版H2不兼容
Hibernate 5.2.12.Final默认依赖的H2版本比Hibernate 4.2.8用的要新很多,旧版H2的认证逻辑和新版不匹配,导致连接时触发密码错误。
解决办法:
强制指定和Hibernate 5.2兼容的H2版本(比如1.4.197,亲测适配没问题),Maven的话在pom.xml里加:
<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.4.197</version> <scope>test</scope> </dependency>
3. JDBC URL格式不符合新版要求
Hibernate 5.x对JDBC URL的解析更严格,比如之前你可能用jdbc:h2:mem:test这种简单格式,但新版H2需要明确指定连接参数,而且如果URL里没带用户名密码,会直接触发认证失败。
解决办法:
修改URL,把用户名密码直接嵌进去,同时加上必要的参数:
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;USER=sa;PASSWORD=
4. Spring集成时的配置传递问题
如果用Spring框架,Hibernate 5.x的JPA集成逻辑有细微变化,可能Spring的数据源配置没正确传递给Hibernate的连接池,导致连接时缺省了用户名密码。
解决办法:
显式配置数据源和EntityManagerFactory,确保参数传递正确:
@Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("org.h2.Driver"); dataSource.setUrl("jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1"); dataSource.setUsername("sa"); dataSource.setPassword(""); return dataSource; } @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource()); em.setPackagesToScan("com.yourpackage.model"); em.setPersistenceProviderClass(HibernatePersistenceProvider.class); // 其他Hibernate配置,比如方言之类的 return em; }
建议先从显式配置用户名密码开始排查,这是最常见的触发原因。如果还是不行,再检查H2版本和URL格式。
内容的提问来源于stack exchange,提问作者Gep

