无法在 Spring Data Cloud Spanner 中将 java.sql.Timestamp 转换为 com.google.cloud.Timestamp

Posted

技术标签:

【中文标题】无法在 Spring Data Cloud Spanner 中将 java.sql.Timestamp 转换为 com.google.cloud.Timestamp【英文标题】:Unable to convert java.sql.Timestamp to com.google.cloud.Timestamp in Spring Data Cloud Spanner 【发布时间】:2020-03-26 22:43:38 【问题描述】:

在使用 Spring Data Cloud Spanner 时,我们无法在 spanner db 中持久化 java.sql.Timestamp 类型的数据。数据库列类型为 Timestamp。

以下是实体:

@Table(name = "TEST")
public class Test 
  
  @PrimaryKey
  @Column(name = “ID”)
  private String id;
 
  @Column(name = "CREATED_ON")
  private java.sql.Timestamp createdOn;


我们正在使用 Spring Data Rest 来持久化。

根据我的分析,我看到已经有一个转换器可以将 java.sql.TimeStamp 转换为 com.google.cloud.Timestamp。

public static final Converter<java.sql.Timestamp, Timestamp> JAVA_TO_SPANNER_TIMESTAMP_CONVERTER =
                    new Converter<java.sql.Timestamp, Timestamp>() 
                        // @formatter:on
                        @Nullable
                        @Override
                        public Timestamp convert(java.sql.Timestamp timestamp) 
                            return Timestamp.of(timestamp);
                        
                    ;

    /**
     * A converter from the Spanner instantaneous time type to @link java.sql.Timestamp.
     */
    // @formatter:off
    public static final Converter<Timestamp, java.sql.Timestamp> SPANNER_TO_JAVA_TIMESTAMP_CONVERTER =
                    new Converter<Timestamp, java.sql.Timestamp>() 
                        // @formatter:on
                        @Nullable
                        @Override
                        public java.sql.Timestamp convert(Timestamp timestamp) 
                            return java.sql.Timestamp.from(TIMESTAMP_INSTANT_CONVERTER.convert(timestamp));
                        
                    ;

而不是在搜索从源类型到目标类型的完美匹配时,由于以下代码 sn-p,它正在 java.sql.Timestamp 到 com.google.cloud.Date 之间得到完美匹配。

public GenericConverter find(TypeDescriptor sourceType, TypeDescriptor targetType) 
            // Search the full type hierarchy
            List<Class<?>> sourceCandidates = getClassHierarchy(sourceType.getType());
            List<Class<?>> targetCandidates = getClassHierarchy(targetType.getType());
            for (Class<?> sourceCandidate : sourceCandidates) 
                for (Class<?> targetCandidate : targetCandidates) 
                    ConvertiblePair convertiblePair = new ConvertiblePair(sourceCandidate, targetCandidate);
                    GenericConverter converter = getRegisteredConverter(sourceType, targetType, convertiblePair);
                    if (converter != null) 
                        return converter;
                    
                
            
            return null;
        

此方法返回源类型 java.sql.Timestamp 的转换器,它实际上负责将 java.util.Date 转换为 com.google.cloud.Date,因为 java.util.Date 是 java.sql.Timestamp 的超类.

【问题讨论】:

您好@ayancancode,我在 Cloud Spanner 团队工作,我们目前正在研究这个特殊问题。请继续关注。 @fuad-malikov 此问题适用于 java.util.Date 和 java.sql.Timestamp。如果我们省略这两种情况,我会看到所有的扳手单元测试都通过了。由于它们之间有继承关系,我们正面临这个问题。请检查我对此修复程序提出的拉取请求的评论。 【参考方案1】:

该问题已在此 PR https://github.com/spring-cloud/spring-cloud-gcp/pull/2065 中得到修复,该修复可在 1.3.0.BUILD-SNAPSHOT 中获得。您能否尝试给我们反馈。

谢谢,

【讨论】:

该修复也应用于 1.2.x 分支,该分支计划于 12 月 18 日作为 1.2.1 版本发布。

以上是关于无法在 Spring Data Cloud Spanner 中将 java.sql.Timestamp 转换为 com.google.cloud.Timestamp的主要内容,如果未能解决你的问题,请参考以下文章

spring data spa 和 oracle 包

Spring Cloud Data Flow初探

如何在 Spring Cloud Data Flow 中为 Spring Batch 作业设置调度程序?

spring-cloud-stream 与测试中的 spring-boot-data-mongodb 冲突

Spring Boot && Spring Cloud系列在spring-data-Redis中如何使用切换库

Spring Cloud Data Flow 编辑现有流