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

Spring Boot连接SQL Server 2022序列生成ID报错求助

Spring Boot连接SQL Server 2022序列生成ID失败排查

问题背景

Spring Boot服务连接SQL Server 2022数据库时,使用序列生成实体ID报错,但同schema下其他表可正常插入数据。

实体代码

public class SomeEntity {
    @Id
    @SequenceGenerator(name = "some_seq", schema = "sch_some", sequenceName = "some_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "some_seq")
    @Column(name = "id", columnDefinition = "decimal")
    private Long id;
    ...
}

插入数据时的错误信息

{"date":"2024-07-07T20:50:08,250Z","env":"test","app":"some-service","version":"1.32.0","host":"_","level":"ERROR","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet]","msg":"Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: error performing isolated work; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: error performing isolated work] with root cause","thread":"http-nio-8080-exec-1","context":[],"eventId":"com.microsoft.sqlserver.jdbc.SQLServerException","stack":"com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name 'some_db.sch_some.some_seq'.\n\tat com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:262)\n\tat com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1624)\n\tat com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:594)\n\tat com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:524)\n\tat com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7194)\n\tat com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2979)\n\tat com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:248)\n\tat com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:223)\n\tat com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(SQLServerPreparedStatement.java:446)\n\tat com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52)\n\tat com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java)\n\tat

## 创建序列的SQL语句
```sql
create sequence SCH_SOME.SOME_SEQ start with 1 increment by 1;

权限尝试问题

怀疑权限问题,按Oracle方式执行grant select on SCH_SOME.SOME_SEQ to [用户名];时,报错:

SQL Error [4606] [S0001]: Granted or revoked privilege SELECT is not compatible with object.

尝试授予UPDATE、ALTER权限也无效果。

Hibernate生成的SQL语句

调试发现Hibernate生成的SQL不符合SQL Server语法:

Hibernate: 
    select
        next_val as id_val 
    from
        some_db.sch_some.some_seq with (updlock,
        rowlock)

解决方案

1. 修正Hibernate方言配置

SQL Server获取序列值的语法是NEXT VALUE FOR [schema].[sequence_name],需确保使用适配SQL Server 2012+的方言:

  • Hibernate 5.x配置:
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
    
  • Hibernate 6.x配置:
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServerDialect
    

2. 修正序列权限

SQL Server中访问序列不需要SELECT权限,执行以下语句授予正确权限:

-- 授予足够获取序列值的REFERENCES权限
GRANT REFERENCES ON SCH_SOME.SOME_SEQ TO [你的数据库用户名];
-- 或者授予ALTER权限(权限范围更大)
GRANT ALTER ON SCH_SOME.SOME_SEQ TO [你的数据库用户名];

3. 验证序列存在性

执行SQL确认序列是否存在且归属正确schema:

SELECT * FROM sys.sequences WHERE name = 'SOME_SEQ' AND schema_id = SCHEMA_ID('SCH_SOME');

4. 检查实体序列配置

当前@SequenceGenerator配置无冗余,但需确保数据库用户能正确识别sch_some schema(可通过指定用户默认schema或在序列名前显式加schema解决)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 11:40:09