Hibernate升级后{h-schema}在JPA原生查询中失效如何解决?
Hibernate 6.6.x 中获取序列nextval的解决方案
问题背景
在Hibernate 6.1.7.Final版本中,以下代码可正常通过Spring Data JPA执行原生查询获取序列下一个值:
@Query(value = "select nextval('{h-schema}cycle_sequence')", nativeQuery = true) fun getId(): Long
但升级至6.6.4.Final版本后该代码失效,原因是Hibernate 6.2及以上版本调整了原生查询的预处理逻辑,不再自动解析{h-schema}这类Hibernate特定占位符(该占位符仅在JPQL/HQL中生效)。
替代方案
方案1:固定Schema直接写入SQL
如果项目的数据库Schema固定,可以直接在原生SQL中指定完整的序列名称:
@Query(value = "select nextval('public.cycle_sequence')", nativeQuery = true) fun getId(): Long
(将public替换为实际使用的Schema名称)
方案2:动态获取Schema并拼接序列名
通过EntityManager动态获取当前持久化单元的Schema,再拼接序列名称执行查询,适配多环境场景:
@Repository class SequenceRepository(private val entityManager: EntityManager) { fun getId(): Long { // 获取默认Schema,无配置时使用public作为 fallback val schema = entityManager.entityManagerFactory.persistenceUnitProperties["hibernate.default_schema"] as String? ?: "public" return entityManager.createNativeQuery( "select nextval(:sequenceFullName)", Long::class.java ) .setParameter("sequenceFullName", "$schema.cycle_sequence") .singleResult } }
方案3:使用JPQL的FUNCTION调用(数据库兼容)
通过JPQL的FUNCTION函数调用数据库原生的nextval方法,同时支持动态传入Schema:
@Query("select function('nextval', concat(:schema, '.cycle_sequence'))", nativeQuery = false) fun getId(@Param("schema") schema: String): Long
调用时传入当前环境的Schema名称即可,该方式无需编写原生SQL,兼容性更强。
内容的提问来源于stack exchange,提问作者Artem Gaidar
相关产品推荐
相关产品推荐

