Spring Boot整合PostgreSQL报错:无法解析PostgreSQL9Dialect
我用Spring Boot搭建PostgreSQL API时碰到了问题,之前搭过好几次同类项目,对比旧项目发现这次操作没太大区别,只是实体类和关联关系不一样。试了加不同依赖,问题还是没解决。
报错信息
2024-02-19T17:07:52.151Z WARN 2851 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to resolve name [org.hibernate.dialect.PostgreSQL9Dialect] as strategy [org.hibernate.dialect.Dialect]
项目配置文件
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.2</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>Back.end</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Text based adventure</description> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
DataLoader代码
package Back.end.demo.Components; import Back.end.demo.Adventurer; import Back.end.demo.Enemy; import Back.end.demo.Location; import Back.end.demo.Repositories.AdventurerRepository; import Back.end.demo.Repositories.EnemyRepository; import Back.end.demo.Repositories.TreasureRepository; import Back.end.demo.Treasure; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; @Profile("!test") @Component public class DataLoader implements ApplicationRunner { @Autowired AdventurerRepository adventurerRepository; @Autowired EnemyRepository enemyRepository; @Autowired TreasureRepository treasureRepository; public DataLoader() { } public void run(ApplicationArguments args){ Adventurer mcfee = new Adventurer("McFee", 0, Location.TOWN, "Fists", 0, true); this.adventurerRepository.save(mcfee); Adventurer mjohnson = new Adventurer("Mary Johnson", 50, Location.GARDEN, "Longsword", 1, true); this.adventurerRepository.save(mjohnson); Adventurer raj = new Adventurer("Raj", 0, Location.FOREST, "Dagger", 0, true); this.adventurerRepository.save(raj); Adventurer greg = new Adventurer("Greg", 500, Location.CASTLE, "Battle Axe", 3, true); this.adventurerRepository.save(greg); Enemy goblin = new Enemy("Goblin", "Dagger", false, Location.GARDEN); this.enemyRepository.save(goblin); Enemy knight = new Enemy("Undead Knight", "Greatsword", false, Location.CASTLE); this.enemyRepository.save(knight); Enemy troll = new Enemy("Troll", "Club", false, Location.FOREST); this.enemyRepository.save(troll); Enemy jester = new Enemy("Jingle the Jester", null, false, Location.GARDEN); this.enemyRepository.save(jester); Treasure diamond = new Treasure("Diamond", 1000, null, Location.CASTLE); this.treasureRepository.save(diamond); Treasure sapphire = new Treasure("Sapphire", 500, null, Location.CASTLE); this.treasureRepository.save(sapphire); Treasure emerald = new Treasure("Emerald", 350, null, Location.GARDEN); this.treasureRepository.save(emerald); Treasure ruby = new Treasure("Ruby", 350, null, Location.GARDEN); this.treasureRepository.save(ruby); Treasure sandals = new Treasure("Winged Sandals of Hermes", 1000, null, Location.CASTLE); this.treasureRepository.save(sandals); Treasure coin = new Treasure("Gold Coin", 50, null, Location.FOREST); this.treasureRepository.save(coin); Treasure blackRuby = new Treasure("Black Ruby of Voldesadt", 1500, null, Location.CASTLE); this.treasureRepository.save(blackRuby); } }
application.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/adventurers spring.datasource.username=postgres spring.datasource.password=postgres spring.jpa.hibernate.ddl-auto=update spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL9Dialect spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
问题原因
Spring Boot 3.2.2依赖的Hibernate版本是6.x,而org.hibernate.dialect.PostgreSQL9Dialect在Hibernate 6.x中已被移除,替换为了新的方言类。
解决步骤
修改application.properties中的方言配置,任选以下一种方式:
- 使用通用PostgreSQL方言(推荐,Hibernate会自动适配对应数据库版本):
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
- 指定对应版本的方言(例如PostgreSQL 10+版本):
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL10Dialect
另外,Spring Boot检测到PostgreSQL数据源时会自动配置正确的方言,你也可以直接删除spring.jpa.database-platform这一行,让框架自动处理。
内容的提问来源于stack exchange,提问作者Ewan Gomolka

