是否可以将雪花与 Spring Boot/JPA/Hibernate 一起使用

问题描述

我正在创建一个直接写入雪花数据库的服务。 我在尝试让 spring 数据 jpa 与 SNowflake 一起有效工作时遇到了很多麻烦。我的主要问题是我无法通过 Jpa Repository 接口 Save 方法将实体保存到 SNowflake DB。由于此应用程序用于将数据转储到 SNowflake,因此能够利用 JPA 会让生活变得更加轻松。

我不想滚动自己的原生查询,所以我的问题是在使用 SNowflake 时是否可以利用 Hibernate。

我想要做的主要事情是使用 Jpa Repositories inbuild Save 方法持久化实体。

以下是我当前的配置。任何关于可以在配置中改进什么以使其工作的想法,或者关于是否可行的任何意见,我们将不胜感激。

spring:
  profiles:
    active: local
  application:
    name: Service
  datasource:
    driverClassName: net.sNowflake.client.jdbc.SNowflakeDriver
    url: ${SPRING_DATASOURCE_URL}
    username: ${SPRING_DATASOURCE_USERNAME}
    password: ${SPRING_DATASOURCE_PASSWORD}
  flyway:
    locations: classpath:db/migration/common,classpath:db/migration/sNowflake
  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.sqlServerDialect
        order_inserts: true
create sequence award_event_id_seq;
create table award_event
(
    id INT NOT NULL DEFAULT award_event_id_seq.nextval PRIMARY KEY,event_source_system                    varchar        not null,event_trigger                          VARCHAR        NOT NULL,event_triggered_by                     VARCHAR        NOT NULL,event_timestamp                        TIMESTAMP      NOT NULL
)
@Entity(name = "award_event")
@SequenceGenerator(name = "award_event_id_seq",sequenceName = "award_event_id_seq",allocationSize = 1)
data class AwardEvent(

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    val id: Int = -1,val eventTrigger: String,val eventTriggeredBy: String,val eventTimestamp: LocalDateTime,val eventSourceSystem: String
)
override fun receiveMessage(message: String) {
        logger.info("Receiving award event: $message")
        val awardEvent: AwardEventMessage = message.toObject()
        // This Save method does not work and throws an error specified below
        awardEventRepository.save(awardEvent.toAwardEvent())
    }
2021-01-08 10:49:28.163 ERROR 3239 --- [nio-9106-exec-1] o.hibernate.id.enhanced.TableStructure   : Could not read a hi value

net.sNowflake.client.jdbc.SNowflakesqlException: sql compilation error:
Syntax error line 1 at position 50 unexpected 'with'.
Syntax error line 1 at position 72 unexpected ')'.
    at net.sNowflake.client.jdbc.SNowflakeUtil.checkerrorAndThrowExceptionSub(SNowflakeUtil.java:124)
    at net.sNowflake.client.jdbc.SNowflakeUtil.checkerrorAndThrowException(SNowflakeUtil.java:64)
    at net.sNowflake.client.core.StmtUtil.pollForOutput(StmtUtil.java:434)
    at net.sNowflake.client.core.StmtUtil.execute(StmtUtil.java:338)
    at net.sNowflake.client.core.SFStatement.executeHelper(SFStatement.java:506)
    at net.sNowflake.client.core.SFStatement.executeQueryInternal(SFStatement.java:233)
    at net.sNowflake.client.core.SFStatement.executeQuery(SFStatement.java:171)
    at net.sNowflake.client.core.SFStatement.execute(SFStatement.java:754)
    at net.sNowflake.client.jdbc.SNowflakeStatementV1.executeQueryInternal(SNowflakeStatementV1.java:245)
    at net.sNowflake.client.jdbc.SNowflakePreparedStatementV1.executeQuery(SNowflakePreparedStatementV1.java:117)

解决方法

作为跟进,我无法使用我上面概述的方法启动和运行应用程序。我仍然不确定为什么,但我认为这可能是因为缺乏对雪花序列作为春季主键的生成类型的支持。

我将生成类型更改为 UUID,应用程序依次开始按预期工作。对需要什么类型的主键没有要求,所以这种方法是令人满意的。

create sequence award_event_id_seq;
create table award_event
(
    id varchar not null constraint award_event_pkey primary key,event_source_system                    varchar        not null,event_trigger                          varchar        not null,event_triggered_by                     varchar        not null,event_timestamp                        timestamp      not null
)
@Entity(name = "award_event")
data class AwardEvent(

    @Id
    @GeneratedValue
    @Type(type = "uuid-char")
    val id: UUID = UUID.randomUUID(),val eventTrigger: String,val eventTriggeredBy: String,val eventTimestamp: LocalDateTime,val eventSourceSystem: String
)