GAEに対応したReflex Coreを公開
Entityとトランザクションでも触れたが、GAE対応したReflex Resource Mapperを公開したいと思う。Reflex Resource Mapperは、XML/JSON⇔JavaBeanのバインディングツールで、JDOと直接マッピングできる点がウリだ。デモサイトを見てもらうとわかるが、ブラウザからJSONを受け取ってJDOに変換してDatastoreに直接保存できる。この処理は以下の2行で書ける。
loginnew = (Login) mapper.fromJSON(req.getParameter("json"));
JdoUtils.insert(loginnew);
デモではJSONを受け取っているが、mapper.fromXML()とすることで同じ構造をしたXMLも受け取れる。
設定も簡単で、4つのjarファイルをGAEのアプリケーションに追加するだけですぐに使うことができる。また、特別な設定ファイルなどは必要ない。
Reflex Core Sample
デモサイト
SVN (Google code)
Reflexでは、RESTfulな新3層アーキテクチャや、APIをやめデータ構造に着目するなどでも説明しているとおり、Entityの設計に重きを置き、その構造のままEntityをCRUD(HTTPでGET/POST/PUT/DELETE)するといったRESTfulな設計を目指す。また、これを容易にするために、reflexentityeditorといったツールや、トランザクション処理に対応したReflexContainerなどを準備している。
JDO設計における注意点
私も嵌ったが親子関係をもつJDOの設計には注意が必要である。以下のようにBeanは基本的にEmbededでない限り、@PersistenceCapableと@PrimaryKeyの定義が必要である。(これは”おまじない”と思った方がいい)
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Content {
・・・
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
・・・
}
さらに、1対多の場合は、子(Content)に親(Login)のプロパティを定義する必要がある。
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Content {
・・・
@Persistent
private Login login;
・・・
}
<関連情報>
JDO problem with owned one-to-many relationships and superclasses
同一型の子Entityを持つと、子Entityの判断がつかない
GAE対応する際に苦労した点
ReflexをGAEに対応させるためにやったことは次のとおり。
1.Making XStream compatible with the Google App Engineを参考に、NoClassDefFoundErrorやExceptionInInitializerErrorをcatchして握りつぶす行を追加。
try {
registerConverter(new PropertiesConverter(), PRIORITY_NORMAL);
} catch (NoClassDefFoundError e) {
} catch (ExceptionInInitializerError e) {
}
2.sun.reflect.ReflectionFactoryを使ったクラスSun14ReflectionProvider.javaからPureJavaReflectionProvider.javaを使うように変更
3.一旦、JDOに保存されたものを取り出すと、java.util.ArrayListオブジェクトがorg.datanucleus.sco.backed.Listに勝手に変わるのでinstance ofが使えない。これはクラス名を指定することで使えるように修正した。
<関連>
JDOから直接SOAP、ATOM。それからDeep Copy
AJAX CRUDサンプルとJDO代替ライブラリ
Pagingをどうやって実現するか
RESTfulアプリのCRUDサンプル -Servlet編-
RESTfulアプリのCRUDサンプル -Modeling編-
0 件のコメント:
コメントを投稿