私は現在、組み込みデータベースのサポートのおかげで、Spring を使用して作成されたインメモリ HSQLDB インスタンスを使用してテスト環境を作成しようとしています。
現在のセットアップ
単体テスト用の「データ ソース」の作成:
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)
リソースとヒント
HSQLDB 2.2.4 を提供する Spring 3.1.1 を使用していますが、ドキュメントに基づいて、正しいことをしていると思います。
ただし、次のような議論:
- これです
- 春のJIRAチケット SPR-8817
HSQLDBとSpringの非互換性/区切り文字の処理方法に起因するエラーであると思われます。
しかし、私はSpringとHSQLDBの両方の初心者であるため、以下の質問があります.
質問
誰かがこれを見たことがありますか?そして、解決策を思いつきましたか?
最終的なストアド プロシージャが{call GetFooById ?}を使用して呼び出される場合、HSQLDB で select-from-where クエリを使用して結果セットを返す同等の方法はありますか?
ResourceDatabasePopulator が原因で、これは効果的に発生する可能性がありますか? ResourceDatabasePopulator は Spring 3.1.1 でも問題を引き起こしていますか?
他のポインター/ヒントはありますか?
よろしくお願いいたします。
M.
編集:
結論と解決策
問題:
ResourceDatabasePopulator はセミコロンをクエリ区切り文字として処理しますが、これは HSQLDB の構文に準拠していません。
{call GetFooById ?}は Sybase (実稼働データベース) では有効な構文ですが、{call GetFooById(?)}を期待する HSQLDB では有効ではありません。もちろん、HSQLDB の構文は Sybase の構文とも互換性がありません。その上、Spring の JdbcTemplate はこれらの違いを抽象化していません。
ソリューション:
SQL ストアド プロシージャの代わりに Java ストアド プロシージャを使用すると、クエリが Java 側で記述され、セミコロン区切り文字が含まれないため、回避策になる場合があります。別の方法として、ResourceDatabasePopulator のロジックを変更して組み込みデータベースをセットアップすることもできると思いますが、これはまだ試していません。
Spring の StoredProcedure クラスは移植性がはるかに高く、JdbcTemplate よりも少し冗長ですが、Sybase と HSQLDB の両方で使用できます。
ソース コード: GitHub リポジトリで入手できます。