You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Spring Boot与Hibernate后单引号内{h-schema}无法解析求助

临时解决Hibernate 7.0.3中单引号内{h-schema}不解析的问题

升级到Spring Boot 3.5.3(对应Hibernate 7.0.3)后,原生SQL里单引号包裹的{h-schema}占位符确实会出现无法被替换的问题,目前可以用以下几种临时方案绕过:

方案一:直接从配置中读取schema名称拼接SQL

通过@Value注入配置好的默认schema,手动拼接到SQL语句中:

import org.springframework.beans.factory.annotation.Value;
import jakarta.persistence.EntityManager;
import org.springframework.stereotype.Repository;

@Repository
public class YourRepository {
    @Value("${spring.jpa.properties.hibernate.default_schema}")
    private String defaultSchema;

    private final EntityManager entityManager;

    public YourRepository(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public Long getNextSeriesId() {
        String sql = String.format("SELECT nextval('%s.workflow_id')", defaultSchema);
        return Long.parseLong(String.valueOf(entityManager.createNativeQuery(sql).getSingleResult()));
    }
}

方案二:通过Hibernate API动态获取schema名称

如果schema是动态变化的(比如多租户场景),可以通过SessionFactory获取当前生效的schema:

import jakarta.persistence.EntityManager;
import org.hibernate.Session;
import org.hibernate.engine.jdbc.spi.JdbcConnectionAccess;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.tool.schema.spi.SchemaNameResolver;
import org.springframework.stereotype.Repository;

@Repository
public class YourRepository {
    private final EntityManager entityManager;

    public YourRepository(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public Long getNextSeriesId() {
        Session session = entityManager.unwrap(Session.class);
        SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor) session.getSessionFactory();
        ServiceRegistryImplementor serviceRegistry = sessionFactory.getServiceRegistry();
        SchemaNameResolver schemaNameResolver = serviceRegistry.getService(SchemaNameResolver.class);
        JdbcConnectionAccess jdbcConnectionAccess = session.getJdbcConnectionAccess();
        
        String schema = schemaNameResolver.resolveSchemaName(jdbcConnectionAccess, sessionFactory.getSessionFactoryOptions());
        String sql = String.format("SELECT nextval('%s.workflow_id')", schema);
        
        return Long.parseLong(String.valueOf(entityManager.createNativeQuery(sql).getSingleResult()));
    }
}

方案三:检查引号策略配置

可以尝试调整Hibernate的标识符引号配置,在application.yml中添加:

spring:
  jpa:
    properties:
      hibernate:
        quote_identifiers: false
        quote_sql_identifiers: false

这个方案不一定能解决问题,但可以排除是引号策略干扰占位符解析逻辑的可能。

注:该问题大概率是Hibernate 7.x版本对原生SQL占位符解析逻辑的变更导致的,在官方补丁发布前,以上方案可作为临时替代。

内容的提问来源于stack exchange,提问作者Tim Malich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 19:19:56