У меня есть приложение 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);
}
}
@Andreas Андреас Я читал это, и в нем не упоминается, что он не поддерживает все функции SQL Server. Голосовать против из-за отсутствия исследований, когда я провел свое исследование и все еще нуждаюсь в помощи, мелочно и не нужно. Если вы предполагаете, что HSQLDB не может делать то, что мне нужно, то это звучит как ответ, который может помочь не только мне, но и другим с этой проблемой в будущем.
Где в вашем исследовании вы обнаружили, что HSQLDB поддерживает типы данных SQL Server? В ссылке, которую вы дали, написано «HyperSQL 2.4 добавляет несколько функции даты и времени в режим совместимости с MSS. К ним относятся DATEPART, DATENAME, EOMONTH и совместимое поведение DATEADD и DATEDIFF». Функции!!! Не типы данных. В разделе «Совместимость с MS SQLServer и Sybase» вообще не упоминаются типы данных столбцов.
@Andreas Андреас Похоже, у тебя плохой день. Я был бы признателен, если бы вы не испортили мою, не дав мне получить помощь. Или этот сайт не помогает людям?
Я помогаю, указывая на то, что вы неправильно прочитали документацию. Или, в случае, если я это сделал, я прошу вас указать мне, где, по вашему мнению, в документации сказано то, что, как вы утверждали, было сказано («Я нашел эту документацию, что по крайней мере некоторые дата/время MS SQL типы и функции поддерживаются»). Указание на ошибки вас не касается? Не отклоняйте помощь только потому, что это указывает на то, что вы чего-то не поняли. Учитесь на этом, то есть не пытайтесь использовать тип данных столбца SQL Server в DDL для HSQLDB.
Обратите внимание, что в руководстве по HSQLDB не перечислены ВСЕ поддерживаемые режимом совместимости функции и имена типов, включая это. Используемая версия OP старше ссылочного документа.




Для типа datetimeoffset SQL вы должны использовать тип java.time.OffsetDateTime Java:
@Column(name = "CreatedDate", nullable = false)
private OffsetDateTime createdDate;
Это если у вас есть JPA версии 2.2 в пути к классам. В противном случае вам нужно будет создать пользовательский конвертер
Я получаю сообщение об ошибке, даже если я оставляю поле вне объекта. Ошибка, которую я получаю, определенно связана с созданием столбца HSQLDB, а не с получением данных из таблицы JPA.
Я буду работать над созданием конвертера, спасибо за внимание!
Я добавил конвертер, и у меня все еще есть эта проблема.
Я использовал LocalDateTime на основе существующей работы в моей организации, но OffsetDateTime будет работать намного лучше для моих нужд и без конвертера для загрузки. Ваш ответ конкретно не ответил на мой вопрос, но все же это был отличный совет. Спасибо за помощь!
Последние версии HSQLDB поддерживают DATETIMEOFFSET в режиме совместимости с MSS. Используйте 2.4.1.
Если вы хотите продолжить использовать более старую версию, которая не поддерживает этот тип, используйте CREATE TYPE DATETIMEOFFSET AS TIMESTAMP WITH TIME ZONE перед созданием таблиц.
Это решило мою проблему. Следует отметить, что в то время как SQL Server может использовать входные данные точности в определении столбца, HSQLDB этого не делает. Это означает, что мои тестовые данные не будут точно соответствовать производственным данным, но в сочетании с изменением OffsetDateTime для @MaciejKowalski я не думаю, что это будет проблемой.
datetimeoffset.