HsqlException: тип не найден или у пользователя нет привилегии: DATETIMEOFFSET - PullRequest
0 голосов
/ 18 апреля 2019

У меня есть приложение 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 в таблицу.

При поиске ответов в Интернете я обнаружил эту документацию , что по крайней мере некоторыеПоддерживаются типы и функции даты и времени MS SQL, но этот (двухлетний) ответ предполагает, что HSQLDB имеет ограниченную поддержку MS SQL.Я не нашел никакой документации, в которой говорится о HSQLDB именно в отношении типа данных datetimeoffset.

Сценарий создания моей таблицы и вставки данных:

    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 ]

1 голос
/ 19 апреля 2019

Последние версии HSQLDB поддерживают DATETIMEOFFSET в режиме совместимости с MSS. Используйте 2.4.1.

Если вы хотите продолжить использовать более старую версию, которая не поддерживает этот тип, используйте CREATE TYPE DATETIMEOFFSET AS TIMESTAMP WITH TIME ZONE перед созданием таблиц.

1 голос
/ 18 апреля 2019

Для типа datetimeoffset SQL вы должны использовать java.time.OffsetDateTime тип Java:

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

Это если у вас есть JPA версии 2.2 в вашем classpath.В противном случае вам нужно будет создать пользовательский конвертер

...