Как использовать последовательности in-mem HSQLDB с модульным тестированием?
Мое приложение использует последовательности, и я пытаюсь настроить тестовую среду junit с базой данных HSQLDB in-mem, которая будет иметь аналогичную настройку. Вот как я настроил последовательности и их создание:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" lazy-init="true"
destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:test"/>
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="logSeqIncrementer" class="org.springframework.jdbc.support.incrementer.HsqlSequenceMaxValueIncrementer">
<property name="dataSource" ref="dataSource" />
<property name="incrementerName" value="public.agent_logs_seq" />
</bean>
<bean id="offerSeqIncrementer" class="org.springframework.jdbc.support.incrementer.HsqlSequenceMaxValueIncrementer">
<property name="dataSource" ref="dataSource" />
<property name="incrementerName" value="public.offers_seq" />
</bean>
<jdbc:embedded-database
id="test"
type="HSQL">
<jdbc:script
location="classpath:/create-ddl.sql" />
</jdbc:embedded-database>
</beans>
И содержимое create-ddl.sql:
CREATE SEQUENCE public.agent_logs_seq;
Приводит к
java.sql.SQLException: Sequence already exists in statement
Но если я прокомментирую это, я получу
java.lang.AssertionError: Unexpected exception:
org.springframework.dao.DataAccessResourceFailureException:
Could not obtain sequence value; nested exception is
java.sql.SQLException: Sequence not found:
AGENT_LOGS_SEQ in statement [call next value for public.agent_logs_seq]
То, как я пытаюсь использовать последовательность:
DataFieldMaxValueIncrementer incrementer =
(DataFieldMaxValueIncrementer) context.getBean("logSeqIncrementer");
Integer logId = Integer.valueOf(incrementer.nextIntValue());
Edit: изменил детали выше, чтобы использовать правильный класс последовательности. Оно однако это не решило проблему.
2 ответа:
У меня была аналогичная проблема, которая поднята здесь.
Были предложены различные решения. База данных H2 показалась мне интересной. В конце концов я вручную отбросил, а затем создал последовательности в сценарии.
Вы указали
org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer
в качестве класса, однако, похоже, Spring используетHsqlSequenceMaxValueIncrementer
(в том же пакете) и создает последовательность, а не таблицу.
HsqlMaxValueIncrementer
- это более старая реализация, которая подходит для платформ баз данных, не поддерживающих объекты последовательности.HsqlSequenceMaxValueIncrementer
является более поздним (Spring V. 2.5) и является более эффективным выбором для HSQLDB. Это должно создать объекты последовательности, которые вы указали, а затем использоватьNEXT VALUE FOR public.agents_logs_seq
внутренне, чтобы получить следующее значение последовательности.