JPA&Hibernate应用切换至MSSQL2016后出现GETDATE语法错误求助
针对你遇到的问题——JPA/Hibernate应用在Oracle环境运行正常,切换到MSSQL2016后用HSQLDB做JUnit测试时出现GETDATE()令牌错误,结合你使用的HSQLDB 1.8.0、Hibernate 3.2.4.sp1和Java7版本,给你几个可行的解决思路:
配置Hibernate对应MSSQL方言
首先确保你的Hibernate配置文件(hibernate.cfg.xml或persistence.xml)里指定了正确的MSSQL方言。因为Hibernate 3.2.4没有专门针对MSSQL2016的方言,你可以尝试使用:<property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>或者如果你的版本支持,用
org.hibernate.dialect.SQLServer2008Dialect,方言会帮助Hibernate自动转换数据库特定函数。增强HSQLDB的MSSQL语法兼容
你已经设置了sql.syntax_mss=true,但HSQLDB 1.8.0对MSSQL函数的映射并不完整。可以在连接URL中手动映射GETDATE()到HSQL支持的函数,比如:jdbc:hsqldb:mem:your_test_db;sql.syntax_mss=true;function.getdate=CURRENT_TIMESTAMP这样HSQLDB会把SQL语句中的
GETDATE()解析成它能识别的CURRENT_TIMESTAMP,也可以换成SYSDATE或NOW(),根据你的需求选择。用HQL跨数据库函数替代原生GETDATE()
如果你的查询是用HQL而非原生SQL,建议使用Hibernate提供的标准函数current_timestamp(),它会根据当前配置的方言自动转换成对应数据库的函数:- Oracle环境:转换成
SYSDATE - MSSQL环境:转换成
GETDATE() - HSQLDB测试环境:转换成
CURRENT_TIMESTAMP
把你的查询条件从effective_date < GETDATE()改成effective_date < current_timestamp(),这样就能避免数据库特定的函数语法问题。
- Oracle环境:转换成
原生SQL的环境适配
如果必须使用原生SQL,可以通过配置文件或者测试类的逻辑来动态替换函数:- 在生产MSSQL环境使用
GETDATE() - 在HSQLDB测试环境替换成
CURRENT_TIMESTAMP
比如在测试类中加载SQL脚本时,做字符串替换,或者用Hibernate的占位符来注入对应环境的函数名。
- 在生产MSSQL环境使用
考虑升级HSQLDB版本(可选)
HSQLDB 1.8.0是比较老旧的版本,新版本(比如2.x系列)对MSSQL的语法兼容更完善,很多函数可以自动识别转换。不过要注意和Hibernate 3.2.4.sp1的兼容性,建议先在测试环境验证后再考虑升级。
内容的提问来源于stack exchange,提问作者Andrew Grothe

