升级Java 9与PostgreSQL 10.4后Hibernate/C3P0连接调试求助
先梳理下你的核心情况:旧代码原本正常运行,升级Java 9和PostgreSQL 10.4后出现连接异常;psql能无密码成功连库,PostgreSQL日志也显示连接已授权,但Hibernate在初始化阶段抛出异常(你贴的日志还没显示完整错误信息)。结合这些信息,我给你几个针对性的排查方向:
1. 优先补全完整的异常栈信息
你贴的Hibernate日志最后以HHH0...截断了,完整的异常信息(包括Caused by嵌套异常部分)是定位问题的关键。不管是类加载失败、连接池初始化超时,还是JDBC驱动兼容性问题,都需要完整异常栈来确认。建议把程序抛出的全部错误信息贴出来。
2. 解决Java 9模块系统的兼容性冲突
Java 9引入的模块化系统会影响旧版JDBC驱动、Hibernate和C3P0的类加载逻辑,这是升级后最常见的坑:
- 升级依赖版本:确保PostgreSQL JDBC驱动是支持Java 9的版本(至少42.2.5+,建议用最新稳定版);Hibernate要升级到5.2.x以上(旧的3.x版本完全不兼容Java 9);C3P0升级到0.9.5.2+。
- 添加JVM启动参数:在程序启动时加上
--add-modules java.sql,java.naming,因为JDBC和JNDI相关模块在Java 9中是可选模块,默认可能不会被自动加载。
3. 修复Hibernate配置中的过时DTD警告
日志里明确提示了DTD命名空间过时:
WARN: HHH000223: Recognized obsolete hibernate namespace http://hibernate.sourceforge.net/. Use namespace http://www.hibernate.org/dtd/ instead.
虽然这个警告不一定直接导致连接失败,但旧DTD在新版Hibernate中可能存在解析隐患,建议修改hibernate.cfg.xml的DOCTYPE声明:
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
4. 显式指定数据库用户名
虽然psql能自动用当前系统用户(dp42)无密码连接,但Hibernate/C3P0在Java 9环境下可能无法自动获取当前用户身份,导致连接时用户名为空。建议在hibernate.cfg.xml中添加用户名配置:
<property name="connection.username">dp42</property>
5. 验证PostgreSQL的TCP/IP身份认证配置
psql默认用Unix套接字连接,而JDBC用的是TCP/IP连接,你需要确认pg_hba.conf中对TCP/IP本地连接的认证规则是trust:
打开pg_hba.conf(通常在PostgreSQL数据目录下),找到类似如下的配置行:
host med dp42 127.0.0.1/32 trust
如果不是trust,改成trust后重启PostgreSQL服务。
6. 检查C3P0连接池的重试逻辑
PostgreSQL日志里重复出现30次连接授权,说明C3P0连接池一直在尝试创建连接但可能未成功,导致不断重试。可以临时调整C3P0配置来减少重试,同时观察异常:
- 保持
hibernate.c3p0.acquire_increment为1(你已经设置了) - 适当增加
hibernate.c3p0.timeout或调整idle_test_period,排查是否是连接超时导致的重试
内容的提问来源于stack exchange,提问作者Dave

