OpenJPAをさらに調べる
GlassFish上で動かすJPA実装をまじめに乗り換えようと思うのでもうちょっと調べてみた。DBはPostgreSQL。
LAZYは問題なく動くか
まったく問題なし。TopLinkと並んで安心して使える。
ID生成は
@GeneratedValue(strategy=GenerationType.AUTO)はGenerationType.TABLEと同じ。
おそらくほとんどの場合、ID生成はGenerationType.IDENTITYだろう。
strategy=GenerationType.IDENTITYは当たり前だがidはinsertせず。
そしてその後
executing prepstmnt 27464544 SELECT CURRVAL('item_id_SEQ')
となって値をシーケンスから取得している模様。これをidのプロパティへセットしているのだろう。
LAZY指定なしの@ManyToOne()
SQLのログを見てもらえると話が早い。
ここではMakerとItemという2つのテーブルを使っている。ItemテーブルがMakerテーブルを参照している。
executing prepstmnt 11263033 SELECT t0.id, t0.商品名, t1.id, t1.生産者名 FROM item t0 LEFT OUTER JOIN maker t1 ON t0.生産者id = t1.id
なんと連結してもってくる。TopLinkだと1件1件明細の数の分検索するのに対して、これは1回のSQLだけだ。件数やDBの種類、テーブルのサイズ等にも影響されると思われるこの問題だが、個人的にはOpenJPAが頭ひとつ抜けてる感じがする。
とはいえTopLinkではキャッシュを積極的に行うのでこのid単位での検索が非効率ではない場合もある。
一方でHibernate EntityManagerとOpenJPAはキャッシングをしないようだ。DBの値をいじると結果もすぐ変わる。TopLinkはキャッシュをオフにするか、キャッシュを破棄して検索させるなどの処理が必要なのだが、この辺は考えなくてもいいようだ。
効率という点ではTopLinkのほうがいいとは思うが、DBを他のツールで直接扱うこともあるのでキャッシュオフにすることが多いことからOpenJPAなどの実装のほうが望ましい。
もっともremoteセッションビーンが可能なのならDBにはアプリケーションサーバー経由でしか触らないと割り切るのもありだと思うが。DBによる排他制御ではなく、アプリケーションによる排他制御もできる(とはいえ、HSQLDBくらいしかあまりやらないと思うけど)し。
persistence.xmlのサンプル
悲観的ロックも可能、SQLがログに出るようにという設定を。
<?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="JPATest-ejbPU" transaction-type="JTA"> <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> <jta-data-source>jdbc/jpa_sample</jta-data-source> <properties> <property name="openjpa.Log" value="DefaultLevel=INFO,SQL=TRACE"/> <property name="openjpa.LockManager" value="pessimistic"/> </properties> </persistence-unit> </persistence>
結論
NetBeansやGlassFishと最も相性のよいJPA実装はOpenJPAで決まり。デメリットはほぼない模様。
そういやJavaEEのコンポーネントで実装を手軽にさしかえができてるのってJPAくらいか。
すべてのコンポーネントがそうなるとうれしいのだけれども。管理ツールの使い勝手とかそっちだけしっかりやってほしいというか。もっともGlassFishV2はTopLink以外満足しているし、V3の起動時間の速さは本当にすごいので変えるつもりはないのだけれども。
[追記]
JUnitがうまくいかない。webからのアクセスだとRemoteでもうまくいくのに。それでも現在最も安定して扱えるJPA実装のようだ。