15

私は現在、組み込みデータベースのサポートのおかげで、Spring を使用して作成されたインメモリ HSQLDB インスタンスを使用してテスト環境を作成しようとしています。

現在のセットアップ

  1. 単体テスト用の「データ ソース」の作成:

    db = new EmbeddedDatabaseBuilder()
             .addDefaultScripts()
             .addScript("stored_procedure.sql")
             .build();
    
  2. 「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 を使用していますが、ドキュメントに基づいて、正しいことをしていると思います。

ただし、次のような議論:

HSQLDBとSpringの非互換性/区切り文字の処理方法に起因するエラーであると思われます。

しかし、私はSpringとHSQLDBの両方の初心者であるため、以下の質問があります.

質問

  1. 誰かがこれを見たことがありますか?そして、解決策を思いつきましたか?

  2. 最終的なストアド プロシージャが{call GetFooById ?}を使用して呼び出される場合、HSQLDB で select-from-where クエリを使用して結果セットを返す同等の方法はありますか?

  3. ResourceDatabasePopulator が原因で、これは効果的に発生する可能性がありますか? ResourceDatabasePopulator は Spring 3.1.1 でも問題を引き起こしていますか?

  4. 他のポインター/ヒントはありますか?

よろしくお願いいたします。

M.


編集:

結論と解決策

問題:

  1. ResourceDatabasePopulator はセミコロンをクエリ区切り文字として処理しますが、これは HSQLDB の構文に準拠していません。

  2. {call GetFooById ?}は Sybase (実稼働データベース) では有効な構文ですが、{call GetFooById(?)}を期待する HSQLDB では有効ではありません。もちろん、HSQLDB の構文は Sybase の構文とも互換性がありません。その上、Spring の JdbcTemplate はこれらの違いを抽象化していません。

ソリューション:

  1. SQL ストアド プロシージャの代わりに Java ストアド プロシージャを使用すると、クエリが Java 側で記述され、セミコロン区切り文字が含まれないため、回避策になる場合があります。別の方法として、ResourceDatabasePopulator のロジックを変更して組み込みデータベースをセットアップすることもできると思いますが、これはまだ試していません。

  2. Spring の StoredProcedure クラスは移植性がはるかに高く、JdbcTemplate よりも少し冗長ですが、Sybase と HSQLDB の両方で使用できます。

ソース コード: GitHub リポジトリで入手できます。

4

1 に答える 1