TopLink+PostgreSQL
TopLink+PostgreSQLに再チャレンジ。Detached Entityの問題がサクサク解決し、Web層からEntityを操作することもできるようになりました。
前回は、Detached Entityの扱いづらさについてエントリしました。
「Web層でエンティティを扱うな!」とは言われても、「POJOなんだから扱えてもいいじゃん。」というのが私の主張。でも、Hibernateの仕様が、そうはさせてくれないことに気づいて、困った。
というのが、あらすじです。
JPAの仕様書には、Detached EntityやLazyロードの仕様はベンダー依存みたいなことも書いてあったので、TopLinkに切り替えてみました。
最初、TopLinkはPostgreSQLでは動かない、とエントリしてましたが、調べてみると設定が足りなかっただけ。少なくとも自分がプロジェクトで用意しているテストケースは、全部クリアしました(なんの保障にもならないw)。
Persistence Unitの設定は、以下のようになります。
transaction-type="RESOURCE_LOCAL">
<provider>oracle.toplink.essentials
.ejb.cmp3.EntityManagerFactoryProvider</provider>
<properties>
<property name="toplink.target-database" value="PostgreSQL"/>
<!-- ↓この指定方法はdeprecatedだそうです。
<property name="toplink.platform.class.name"
value="oracle.toplink.essentials.platform
.database.PostgreSQLPlatform" />
-->
<property name="toplink.jdbc.url"
value="jdbc:postgresql://localhost:5432/dbname"/>
<property name="toplink.jdbc.driver"
value="org.postgresql.Driver"/>
<property name="toplink.jdbc.user" value="username"/>
<property name="toplink.jdbc.password" value="password"/>
<property name="toplink.ddl-generation"
value="drop-and-create-tables"/>
</properties>
</persistence-unit>
Exceptionが発生するポイントが違います。私の希望としては、エンティティの整合チェックは、エンティティのアクセサを触ったときではなく、EntityManager APIを操作したときであってほしい。
Hibernateでは、Detached Entity のアクセサを触った時点で、Exceptionが発生。これは余計なおせっかい。
TopLinkでは、EntityManagerコンテキスト外でのLazyロードでもExceptionにはならない(IndirectListオブジェクトが返るだけ)し、関連操作も自由自在。
これは結構、大きな違いかと。
前回のコードをTopLinkを使って修正してみると、次のようになります。
EntityManager em = getEntityManager();
UserRole role = em.find( UserRole.class, "role_name" );
List users = role.getUsers();
for( Object o: users ){ // 関連してるUserをLAZYフェッチ
;
}
em.close(); //この時点で、roleはdetached状態に。
//このroleにUserを新規に登録したい
User user = new User();
user.setName("takeda");
user.setUserRole( role );
role.addUser( user );
//Hibernateなら、この時点でException
// TopLinkなら、OK。
em = getEntityManager();
em.merge( role );
//detachedから回復&ユーザー登録
// role-user間にcascade設定してれば、これだけ。
em.close();
ということで、おかげさまで予定通り、@EntityをWeb層のDTO(POJO)として扱うことができるようになりました。TopLinkに切り替えたとたん、感覚的に素直にサクサクと作れて作業効率は3倍増です。
ただし!これでプロジェクトを進めると、もうHibernateに逆戻りはできなくなるのである。こえ~。

