ポータブルなWEB-DBアプリケーションのために、HSQLDBの”In-Memory Database”を使う方法を紹介しました。
ただし、メモリ中で動作させているために、中身のデータを閲覧することがしづらいという問題がありました。
本当は、データベースファイルを使用するIn-Process (Standalone)モードで、作りたかったのですが、ファイルがロックされてしまい、複数の接続を作成することができないと思ったのです。
HSQLDBのクライアントを2つ立ち上げ、同一のデータベースファイルに接続を試してダメだったためです。
調べてみたらIn-Processモードでも複数のConnectionを取得できることが分かりました。
その条件は、“同一VM中であること”です。
Webアプリケーションの場合は、同一VM中で動作させるため問題がありません。以前に試した方法は、VMを2つ立ち上げてしまったため、複数のConnectionを得られなかったのです。
In-Processモードを使えば、ファイルを使って永続化できます。
Webアプリケーションで、読み書きしたデータがどうなっているか、ツールを使って確認することができます。
ただし別VMを立ち上げて接続することになるので、Webアプリケーションを一旦停止してからでないと接続できません。また逆にツールで接続している間に、Webアプリケーションを起動してしまうと、Webアプリケーションが接続できません。
ちょっと不便がありますが、それでもツールで確認できる利点は価値ありだと思います。
ちなみに、このポータブルなWebアプリケーションは、サンプルの提供として使ってください。
データの永続化が重要でないケースで使ってください。
In-Processモードを使った方法
ほとんど以前と同じ方法です。
- データベースファイルを用意する
- WEB-INF/db配下に、データベースファイルを配置する
- Filterのinit時に、In-Processモードで接続するDataSourceを作成する
- Filterのdestroy時に、SHUTDOWNと、Timerの停止を行う
データベースファイルの用意は、HSQL Database Managerなどを使って用意しておきます。
(Eclipseのプラグイン等で、接続して作成してもOKです)
正常に切断すると、*.propertiesと、*.scriptというファイルが残ります。
*.lckとか*.logが残っている場合は、SHUTDOWNせずに切断した可能性があります。
SHUTDOWNすると、.logの内容が.scriptに記録されて.logは消えるはずです。
(※CACHED tableを使っていると、.dataも対象になります。)
この2つのファイルを、WEB-INF/dbというフォルダを用意し、そこに格納します。
場所はここでなくてもよいのですが、ポータブルであることから、Webアプリケーションコンテキストの配下であるべきです。
データベースファイルのパスは静的に記述すると、ポータブルでなくなってしまうので、、動的に設定します。Filterのinit時に、コンテキストパスから作成しています。
String path = config.getServletContext()
.getRealPath("/WEB-INF/db/onlywar")
最後にdestroy時に、おまじない的な処理を追加します。
SHUTDOWNは、データベースファイルをフラッシュさせるものです。
これだだと、Webアプリケーションの再ロード時に、
Exception in thread "HSQLDB Timer @10275fa"
java.lang.NullPointerException
こんな例外が発生してしまいます。
それを防ぐために、以下のようにTimerを停止させてみました。
DatabaseManager.getTimer().shutDown();
以上で、In-Processモードで動作するポータブルWEB-DBアプリが作成できました。
サンプルはこちらです。(ソース付きWAR)