JackRabbitのリポジトリをファイルからDBに移行する

コンテンツリポジトリJava API(JCR)実装であるJackRabbitのリポジトリを移行しようとしてハマったのでメモ。

参考リンク

を見ると、JackRabbitの機能でXMLでExportしてImportする方法とかが紹介されている。しかし、試すとうまく移行できない。

今回はリポジトリ内の特定ノードだけ移行したいのではなく、リポジトリを丸ごと移行したい。正確には、データストアとしてファイルシステムを使っていたのを、データベースにただ変更したいだけ。ファイルシステムリポジトリ --> データベースのリポジトリに変換したいだけなのだが、Export、Importツールは特定ノードに移行には使えそうだが、リポジトリ丸ごととなるとどうもうまく動いてくれない。

結局のところ、リポジトリ丸ごと移行であれば、JackRabbitに用意されているRepositoryCopier APIを使うのがよさそうです。

ただし、JackRabbitのバグなのか、そのままこのAPIを使用するとコピーの途中で「com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'deadbeef-face-babe-cafe-babecafebabe' for key ...」と一意制約違反によるエラーが発生して最後まで完了しない現象となった。どうも、本来であればUPDATE文を発行すべきところをINSERT文で更新しようとしてエラーとなっているようです。

というわけで、JackRabbitにちょっとしたパッチをあてつつコピーツールを作成してみた。GitHubで公開しておきます。

使い方

Git cloneでソースを取得し、gradlewでビルドする。

git clone https://github.com/wadahiro/jackrabbit-copy-tool.git
gradlew distZip

build/lib/jackrabbit-copy-tool-{version}.zipが作成されるので、これをJackRabbitのデータを置いているサーバにインストールする。unzipで解凍するだけ。

以下のコマンドでリポジトリのコピーを実行する。パラメータとして、コピー元の設定ファイル・ディレクトリ、コピー先の設定ファイル・ディレクトリを指定すること。

cd jackrabbit-copy-tool/bin/
jackrabbit-copy-tool -sc /jackRabbitDir/repository.xml -sd /jackRabbitDir/home -tc /anotherJackRabbitDir/repository.xml -td /anotherJackRabbitDir/home