В настоящее время я пытаюсь создать среду тестирования с использованием экземпляра HSQLDB в памяти, созданного с помощью Spring, благодаря поддержке встроенных баз данных:
Текущая настройка
-
Создание "источника данных" для моих модульных тестов:
db = new EmbeddedDatabaseBuilder() .addDefaultScripts() .addScript("stored_procedure.sql") .build();
-
Содержимое "stored_procedure.sql":
-- Mock of a more complex stored procedure in production environment CREATE PROCEDURE GetFooById(IN fooId VARCHAR(12)) READS SQL DATA DYNAMIC RESULT SETS 1 BEGIN ATOMIC DECLARE resultSet CURSOR WITHOUT HOLD WITH RETURN FOR SELECT name, value FROM Foos WHERE id = fooId; OPEN resultSet; END
Проблема
Я могу инициализировать мою схему и вставить свои данные тестирования из "скриптов по умолчанию" без каких-либо проблем.
Однако при создании процедуры я вижу ошибки, подобные приведенным ниже, даже после разных версий вышеупомянутого SQL с разделителями/без разделителей и с разделителями в разных положениях:
java.sql.SQLSyntaxErrorException: unexpected end of statement: required: ; at org.hsqldb.jdbc.Util.sqlException(Unknown Source) at org.hsqldb.jdbc.Util.sqlException(Unknown Source) at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source) at org.hsqldb.jdbc.JDBCStatement.executeUpdate(Unknown Source) at org.springframework.jdbc.datasource.init.ResourceDatabasePopulator.executeSqlScript(ResourceDatabasePopulator.java:169)
Ресурсы и подсказки
Я использую Spring 3.1.1, который предоставляет HSQLDB 2.2.4, и, основываясь на документации, я думаю, что я поступаю правильно.
Однако такие дискуссии, как:
- Этот
- Spring билет JIRA SPR-8817
заставляет меня думать, что это может быть несовместимость между HSQLDB и Spring/ошибкой, вызванной обработкой разделителей.
Но я начинаю как в Spring, так и в HSQLDB, поэтому мои вопросы ниже.
Вопросы
-
Кто-нибудь когда-либо видел это раньше? И придумал решение?
-
Есть ли эквивалентный способ возврата набора результатов с помощью запроса select-from-where в HSQLDB, учитывая, что окончательная хранимая процедура вызывается с помощью {call GetFooById?}?
-
Может ли это быть эффективно из-за ResourceDatabasePopulator? Является ли ResourceDatabasePopulator все еще вызывающим проблемы в Spring 3.1.1?
-
Любой другой указатель/подсказка?
Заранее спасибо за вашу помощь.
М.
EDIT:
Заключение и решения
Проблемы
-
ResourceDatabasePopulator обрабатывает точки с запятой как разделители запросов, что не соответствует синтаксису HSQLDB.
-
{вызов GetFooById?} является допустимым синтаксисом для Sybase (моя производственная база данных), но не для HSQLDB, который ожидает {вызов GetFooById (?)}, И, конечно же, синтаксис HSQLDB несовместим с Sybase one. Кроме того, Spring JdbcTemplate не абстрагирует эти различия.
Решения
-
Использование хранимых процедур Java вместо хранимых процедур SQL может быть обходным путем, поскольку запрос написан на стороне Java, и не используются разделители с разделителями. В качестве альтернативы, я думаю, логика ResourceDatabasePopulator может быть изменена и использована для настройки встроенной базы данных, но я пока этого не пробовал.
-
Spring Класс StoredProcedure выглядит гораздо более переносимым и может использоваться как с Sybase, так и с HSQLDB, даже если он немного более подробный, чем JdbcTemplate.
Исходный код: доступен в моем репозитории GitHub.