HsqlException:找不到类型或用户缺乏特权:DATETIMEOFFSET

时间:2019-04-18 17:58:55

标签: java sql spring-boot spring-data-jpa hsqldb

我有一个Java 8,Spring Boot 2应用程序,其中JPA实体连接到MS SQL Server数据库。我正在尝试使用HSQLDB(2.3.3)创建集成测试,如果我不包括审核信息(创建日期,上次更新等),该测试会很好。

这是我收到的错误消息:

Caused by: org.hsqldb.HsqlException: type not found or user lacks privilege: DATETIMEOFFSET

我了解到“找不到类型或用户缺乏特权”错误是通用错误,可能是由多种原因引起的。在这种情况下,我知道如果不尝试向表中添加datetimeoffset列,一切都会正常运行。

在网上寻找答案时,我发现this documentation至少支持某些MS SQL日期/时间类型和功能,但是this (two-year-old) answer暗示HSQLDB仅对MS SQL提供有限的支持。我还没有找到任何有关dateSQLoffset数据类型的有关HSQLDB的文档。

我的表创建和数据插入脚本:

    DROP SCHEMA TEST IF EXISTS;
    CREATE SCHEMA TEST;

    CREATE TABLE TEST.Example (
      ID int IDENTITY NOT NULL,
      Name nvarchar(30) NOT NULL,
      Description nvarchar(1000),
      CreatedDate datetimeoffset(7) NOT NULL
    );

    INSERT INTO TEST.Example (ID, Name, Description, CreatedDate) 
    VALUES (1, 'First', 'This is the first example.', '2019-04-18 12:00:00 -05:00');

我的数据源配置:

    config:
      datasource:
        jdbc-url: jdbc:hsqldb:mem:testdb;sys.syntax_mss=true
        driver-class-name: org.hsqldb.jdbc.JDBCDriver
        validation-query: SELECT 1
        test-on-borrow: false
        test-while-idle: true
        time-between-eviction-runs-millis: 60000
        max-active: 10

我的实体:

    @Data
    @Entity
    @Table(name = "Example", schema = "TEST")
    public class ExampleEntity {    
        @Id
        @Column(name = "ID", unique = true, nullable = false)
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int id;

        @Column(name = "Name", nullable = false)
        private String name;

        @Column(name = "Description")
        private String description;

        @Column(name = "CreatedDate", nullable = false)
        private LocalDateTime createdDate;    
    }

我的存储库:

    public interface ExampleRepository extends CrudRepository<ExampleEntity, Integer> {
    }

我的集成测试配置:

    @Configuration
    @EnableJpaRepositories(
        basePackages = "com.test.example.repository",
        entityManagerFactoryRef = "integrationTestEntityFactory",
        transactionManagerRef = "integrationTestTransactionManager")
    public class IntegrationTestConfig {
        @Bean
        @ConfigurationProperties(prefix = "config.datasource")
        public DataSource integrationTestDatasource() {
            return new EmbeddedDatabaseBuilder()
                .addScript("scripts/schema.sql")
                .build();
        }

        @Bean
        public LocalContainerEntityManagerFactoryBean integrationTestEntityFactory(final DataSource integrationTestDatasource) {

            HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
            vendorAdapter.setDatabase(Database.SQL_SERVER);
            vendorAdapter.setShowSql(false);

            LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
            factory.setJpaVendorAdapter(vendorAdapter);
            factory.setPackagesToScan("com.test.example.entity");
            factory.setDataSource(integrationTestDatasource);
            return factory;
        }

        @Bean
        public PlatformTransactionManager integrationTestTransactionManager(final LocalContainerEntityManagerFactoryBean integrationTestEntityFactory) {
            JpaTransactionManager transactionManager = new JpaTransactionManager();
            transactionManager.setEntityManagerFactory(integrationTestEntityFactory.getObject());
            return transactionManager;
        }

        @Bean
        public NamedParameterJdbcTemplate integrationTestJdbcTemplate(final DataSource integrationTestDatasource) {
            return new NamedParameterJdbcTemplate(integrationTestDatasource);
        }
    }

2 个答案:

答案 0 :(得分:1)

对于datetimeoffset SQL类型,您应该使用java.time.OffsetDateTime Java类型:

    @Column(name = "CreatedDate", nullable = false)
    private OffsetDateTime createdDate; 

这是如果您的类路径中有版本2.2中的JPA。否则,您需要创建一个custom converter

答案 1 :(得分:1)

最新版本的HSQLDB在MSS兼容模式下支持DATETIMEOFFSET。使用2.4.1。

如果要继续使用不支持此类型的旧版本,请在创建表之前使用CREATE TYPE DATETIMEOFFSET AS TIMESTAMP WITH TIME ZONE