ラベル Java の投稿を表示しています。 すべての投稿を表示
ラベル Java の投稿を表示しています。 すべての投稿を表示

2012年12月8日土曜日

[GAE/J] 登録エラー

背景

GAE/Jで登録時に以下のエラーとなる。
JDOによりデータベース設計してます。
Uncaught exception from servlet java.lang.IllegalStateException: Primary key for type Title is of unexpected type java.lang.Integer (must be String, Long, or com.google.appengine.api.datastore.Key) at com.google.appengine.datanucleus.DatastoreFieldManager.exceptionForUnexpectedKeyType(DatastoreFieldManager.java:162) at com.google.appengine.datanucleus.StoreFieldManager.storePrimaryKey(StoreFieldManager.java:481) at com.google.appengine.datanucleus.StoreFieldManager.storeObjectField(StoreFieldManager.java:179) at org.datanucleus.state.AbstractStateManager.providedObjectField(AbstractStateManager.java:1447)

原因

プライマリーキーとしてInteger型は受け入れられない模様。
Long型に変更したら解決しました。


2012年11月18日日曜日

[GAE/J] DatastoreのM/SからHRDへの移行 体験記


[Google App Engine(GAE)] のDatastore を [Master/Slave Datastore(M/S)] から [High Replication Datastore(HRD)] への移行した時の体験を記録しておきます。
対象としたサービスは大喜利部のサーバサイドプログラムです。

背景

2012/08/24 GAEからM/S利用者へ向けてHRDへの移行を推奨メールが送信されました。
要約すると、M/Sは廃止します。ツールを用意したので、HRDへの移行をお勧めします。
といった内容です。
また、GAEの管理サイトでは以下のような画面が表示されるようになり、移行を決意しました。


対象アプリのデータ量は目安として、大きなKindは以下の2つ。
 お題Kind 200万レコード
 ボケKind 3万レコード
 他にも15 Kind 程 存在します。

事前準備

2012/11/10 00:00〜開始しました。(この記事を書きながらなので、目安程度に考えてください)
事前準備としてサーバメンテナンスをお知らせしてありましが。
アプリに大してもメンテナンス中には操作できなくなるように細工をしてあり、その細工を開始します。

サーバの複製をしていきます。
管理ツールメニュー(左側)の[Administration]-[Application Settings]を開きます。
下の方に[Duplicate Application Settings]がありますので、複製を開始していきます。

複製アプリ名を[New Application Identifier]に入力し、[Check Availability]で使用できる名称かチェックし、[Duplicate Application...]を選択します。
My Applications へ移動し、HRDのアプリが複製されました。

複製アプリに現行アプリをデプロイ

複製アプリに、現アプリをデプロイします。
[appengine-web.xml]ファイルの[application]タグの名称を更新してデプロイを実行。(このとき私はversionを1に戻しました)

(ここまでの完了時間 11/18 00:50)※これを書きながらなので非常に時間がかかっています。

[Datastore Indexes]が、インデックスが[Serving]に変わるまで待ちます。
インデックスは25ほどありますが、全て0Entityなので、結構すぐ終わります。
(完了したのが、11/18 01:00 <約10分かかりました>)

データの移行

ツールを使ってデータを移行していきます。
現行サーバの管理ツールメニュー(左側)の[Administration]-[Application Settings]を開き、[Migrate Application]-[View Migrate Tool...]を選択します。

[Desination Application]でMigrationするデータベースを選択し、[Start Migration]を選択して、移行を開始していきます。(メールに通知するかのチェックボックスがあります)
[All blobs and references to those blobs will automatically be migrated. However, any serialized references to blobs must bemigrated manually.]の一文が気になりますが、後で対応します。


ステップは以下の通りです。
1.Catch up
2.Copy
3.Waiting    (このステップではここまで進むことになります)
4.Sync
5.Read-only
6.Catch up
7.Sync
8.Alias

移行を開始したのは、11/18 01:30です。
進行状況は[Administration]-[Application Settings]を開き、[Migrate Application]-[View Migrate Tool...]と進むと進行画面を再度見ることができます。

[3.Waiting]になり完了メールが来たのが、11/18 02:30 で約1時間かかりました。

現行アプリをRead-onlyにする

現行アプリをRead-onlyにします。(このステップでは[8.Alias]まで進みます)
[Activete Read-only]実行できますが、[Launch Incremental Copy]を実行すると、移行中の増減などの取りこぼしを防げるようになります。

[Launch Incremental Copy]を押して、開始します。(11/18 02:45 開始)
更新がほとんどなかったので、10分程度で終了。

続けてActivate Read-only をクリックし、読み取り専用にします。(11/18 02:55 開始)
11/18 03:10 <15分程度>で完了しました。
Syncしてるので、再同期してると思いますので、[Launch Incremental Copy]は不要かもしれません。

完了!

最後に[Finish Migration]して、移行を完了します。

比較的簡単に完了できました。
後はアプリで確認などしていきます。
[Billing Setting]がクリアされていますので、再度設定してください。

気になったこと

移行後、[Datastore Viewer]を参照してもデータがない場合がありました。
移行直後は時間がインデックスが更新されるまでに時間がかかるのかな?
アプリで普通に参照はできるのに、[Datastore Viewer]では参照できない状態にありますした。
時間が立った今は、1秒もすればインデックスとして適用され表示されますが、始め混乱しました。
皆様も混乱しないようにしてください。


もう一つ困ったことが。
[Blob]を利用している場合、新旧で[Blob key]が変わっています。これの対策もする必要があります。
詳細は別記載しましたので、下の記事を参照ください。

[GAE/J] M/SからHRDへ移行時のBlobkey振り替え対応

背景

[Google App Engine(GAE)] のDatastore を [Master/Slave Datastore(M/S)] から [High Replication Datastore(HRD)] への移行しました。
対象としたサービスは大喜利部のサーバサイドプログラムなのですが、Blobを使用しています。

移行した際、Blobkeyは振り直しされるようで、移行後は旧DatastoreのBlobkeyをデータベースに保持するようにしていると、移行後に参照できなくなてしまいます。

[GAE]では[Python]で使用できる、[BlobMigrationRecord]クラスが用意されており、
[.get_new_blob_key(old_key)]というメソッドが用意されているのですが、Javaではこのクラスがなく、以下の方法で回避したので、記録しておきます。
The BlobMigrationRecord Class

解決方法

あまり記載がなく苦労したのですが、どうやら移行した際のBlobKeyの新旧のBlobkeyは「__BlobMigration__」というKindで管理されているようです。

よって、管理ツールの[Datastore Viewer]でSelect分を実行すると新旧の紐付けが分かるということになります。
[ SELECT * FROM __BlobMigration__ ]

つまり、これらを紐づけるようにすれば良い訳です。

[BlobMigrationRecord Class] get_new_blob_key() method for Java

Pythonと同じような[BlobMigrationRecord]の[get_new_blob_key()]メソッドと同じことができるJava版を作ってみましたので掲載しておきます。
自由に使っていただいて問題ないです。
(「いいね」とか「+1」とか「コメント」とかもらえると喜びます)

eclipse4.2インストール 体験記

背景

eclipse3.7を利用していたのだが、なぜか起動すると、システムエラーに。
仕方がないので、この際なので最新バージョン(4.2)を導入することにしました。

eclipse ダウンロード

下のページで[Eclipse IDE for Java Developers]をダウンロード。
Eclipse Downloads

解凍し、eclipse起動まで問題なく動作。

Plugin インストール

とりあえず、直近で必要なPluginは[Google App Engine]だけなので、下のページの通りに、インストールを実施。
Google Plugin for Eclipse 4.2(Juno)
以下のプラグインをインストールする訳だが、
http://dl.google.com/eclipse/plugin/4.2Android関連のダウンロードが過去の経験上分かっていたので、[Google App Engine]に必要な内容だけに絞りインストールしました。(他はまた時間があるときにインストールしようと考えています)
・Google App Engine Tool for Android
・SDKs
   Google Web Toolkit SDK
   Google App Engine SDK

なんなくインストールが完了しました。

[Google App Engine]へデプロイ

既存の[Google App Engine]アプリを開いたときにバージョンがあがったためだと思いますが、[App Engine SDK]へのパスが外れていたので、設定し直しました。

いざ、デプロイしようとすると以下のようなエラーが。

どうやら、appengine-web.xml に<threadsafe>タグ(マルチスレッドとするか)がなかったためにエラーとなっていました。

これで、デプロイすると、無事配置ができました。

参考