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

Spring Boot迁移至Cloud Spanner遇DirectedReadOptions类缺失错误

Spring Boot迁移Cloud Spanner时的类缺失错误解决

问题场景

将基于Spring 3、Java 17,使用最新Hibernate和JPA的Spring Boot应用从Cloud SQL(PostgreSQL)迁移到Cloud Spanner,采用Google SQL方言交互时,启动报错。

错误日志

Caused by: java.lang.ExceptionInInitializerError: null
    at com.google.cloud.spanner.connection.ConnectionImpl.<clinit>(ConnectionImpl.java:135)
    at com.google.cloud.spanner.connection.ConnectionOptions.getConnection(ConnectionOptions.java:1073)
    at com.google.cloud.spanner.jdbc.AbstractJdbcConnection.<init>(AbstractJdbcConnection.java:65)
    at com.google.cloud.spanner.jdbc.JdbcConnection.<init>(JdbcConnection.java:56)
    at com.google.cloud.spanner.jdbc.JdbcDriver.connect(JdbcDriver.java:196)
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:121)
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359)
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201)
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470)
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:100)
    at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:81)
    at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:208)
    ... 37 common frames omitted
Caused by: com.google.cloud.spanner.SpannerException: INTERNAL: Could not instantiate statement parser for dialect GOOGLE_STANDARD_SQL
    at com.google.cloud.spanner.SpannerExceptionFactory.newSpannerExceptionPreformatted(SpannerExceptionFactory.java:319)
    at com.google.cloud.spanner.SpannerExceptionFactory.newSpannerExceptionPreformatted(SpannerExceptionFactory.java:325)
    at com.google.cloud.spanner.SpannerExceptionFactory.newSpannerException(SpannerExceptionFactory.java:62)
    at com.google.cloud.spanner.connection.AbstractStatementParser.getInstance(AbstractStatementParser.java:93)
    at com.google.cloud.spanner.connection.AbstractStatementParser.<clinit>(AbstractStatementParser.java:145)
    ... 55 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
    at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:74)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
    at com.google.cloud.spanner.connection.AbstractStatementParser.getInstance(AbstractStatementParser.java:91)
    ... 56 common frames omitted
Caused by: com.google.cloud.spanner.connection.ClientSideStatementImpl$CompileException: Could not compile statement SHOW VARIABLE AUTOCOMMIT
    at com.google.cloud.spanner.connection.ClientSideStatementImpl.compile(ClientSideStatementImpl.java:159)
    at com.google.cloud.spanner.connection.ClientSideStatements.getCompiledStatements(ClientSideStatements.java:76)
    at com.google.cloud.spanner.connection.SpannerStatementParser.<init>(SpannerStatementParser.java:41)
    at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
    ... 59 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
    at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:74)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
    at com.google.cloud.spanner.connection.ClientSideStatementImpl.compile(ClientSideStatementImpl.java:156)
    ... 62 common frames omitted
Caused by: java.lang.NoClassDefFoundError: com/google/spanner/v1/DirectedReadOptions
    at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
    at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3578)
    at java.base/java.lang.Class.getDeclaredMethod(Class.java:2846)
    at com.google.cloud.spanner.connection.ClientSideStatementNoParamExecutor.<init>(ClientSideStatementNoParamExecutor.java:39)
    at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
    ... 65 common frames omitted
Caused by: java.lang.ClassNotFoundException: com.google.spanner.v1.DirectedReadOptions
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
    ... 70 common frames omitted

当前依赖配置

<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-spanner-hibernate-dialect</artifactId>
    <version>3.3.0</version>
</dependency>
<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-spanner</artifactId>
    <version>6.80.1</version>
</dependency>
<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>spring-cloud-gcp-data-spanner</artifactId>
    <version>5.8.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-rest</artifactId>
    <version>3.3.5</version>
</dependency>
<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-spanner-jdbc</artifactId>
    <version>2.8.0</version>
</dependency>

解决方法

1. 统一Spanner相关依赖版本

核心问题是google-cloud-spanner(6.80.1)和google-cloud-spanner-jdbc(2.8.0)版本不兼容,导致gRPC proto类缺失。建议使用Spring Cloud GCP的BOM来统一管理所有Google Cloud依赖版本,避免手动指定版本冲突:

在pom.xml中添加依赖管理:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>spring-cloud-gcp-dependencies</artifactId>
            <version>5.8.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

然后调整依赖,移除手动指定的版本号:

<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-spanner-hibernate-dialect</artifactId>
</dependency>
<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-spanner</artifactId>
</dependency>
<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>spring-cloud-gcp-data-spanner</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-spanner-jdbc</artifactId>
</dependency>

2. 清理依赖缓存并重新构建

执行Maven命令清理并重新下载依赖:

mvn clean install -U

3. 检查冗余依赖

如果你的应用仅使用Hibernate/JPA访问Spanner,可考虑移除spring-cloud-gcp-data-spanner依赖,避免两种数据访问框架冲突;如果同时需要Spring Data Spanner的Repository支持,则保留该依赖。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 03:50:54