Kuina-Daoに挑戦 その2

昨日の日記で幾つか上げた問題点ですが、どうやら解決できそうです。
まずは、TopLinkが存在しないNamedQueryの名前を渡してもエラーを返さない問題についてですが、Queryの実装クラスを調べたところ、getDatabaseQueryというメソッドの中でNamedQueryの存在チェックを行っていました。そしてこのgetDatabaseQueryメソッドは、setParameterやsetHintやgetResultListなど、さまざまなメソッドから呼ばれています。createNamedQueryを呼び出した直後に実行しても特に問題なさそうなメソッドだったので、これを呼ぶようにAspectで修正をかけることにしました。
続いて、パラメータのバインドに失敗する問題・・・というか問題ではなくて、自分がDiiguを導入してなかっただけでした(汗)・・・どうもすみません・・・
というわけで、EntityManagerにアスペクトをかけて、Diiguを導入した状態で再度実行してみました。
まずは、find

Employee find(Integer id);

これを実行すると

SELECT ID, NAME, VERSION FROM EMPLOYEE WHERE (ID = ?)
	bind => [1]

まずはこれでOK。次にfindAll

List<Employee> findAll();
SELECT ID, NAME, VERSION FROM EMPLOYEE

これもいいですね。次はNamedQuery

List<Employee> findByName(String name);
<named-query name="Employee.findByName">
	<query>
		SELECT emp FROM Employee emp WHERE emp.name = :name	
	</query>
</named-query>

・・・XMLの問題はひとまず置いといて・・・結果は

SELECT ID, NAME, VERSION FROM EMPLOYEE WHERE (NAME = CAST (? AS VARCHAR(32672) ))
	bind => [test]

・・・ん?何故CASTしてるんだろう?・・・でもまぁいいか。
次はExample

        Employee employee = new Employee();
        employee.setId(1);
        employee.setName("test");
        employeeDao.findByExample(employee);
SELECT ID, NAME, VERSION FROM EMPLOYEE WHERE ((ID = CAST (? AS INTEGER )) AND (NAME = CAST (? AS VARCHAR(32672) )))
	bind => [1, test]

CASTするような仕組みになってるのかな? とりあえず大丈夫そうですね。
最後に、個人的に気になっている、SQLでの実行を試してみました。

 List<EmpDto> findByNameSql(String name);

SQLセミナーに出ていた例題を、ファイル名だけ変えてそのまま使いました。
結果は・・・ってログが出なかったのですが、デバッグで追ったところ、しっかり実行されていました。
細かな部分の確認がまだまだ出来ていませんが、なんとかTopLinkKuina-Daoを動かせそうです。そして・・・動かしてみて気づいたのですが、Kuina-DaoによってTopLinkの最大の弱点・・・SQL関連の対応をほぼカバーすることが出来るんですね。ということは・・・Entityのロード制限さえ問題なければ、場合によってはHibernateよりもTopLink + Kuina-Daoの組み合わせの方が向いている状況というのは、結構出てくるのかもしれません。SQL対応の点でTopLinkHibernateに差をつけられていると感じていたのですが、Kuina-Daoを使えばほぼ五分になり、そしてN:1のLAZYロードについてはTopLinkの方が優れていますから。あとは、TopLinkの実行環境面での問題(Entityのロード問題)とHibernateの豊富な独自機能、ここら辺を天秤にかければ、2つのJPA実装を比較検討する価値は十分出てくるのではないかと思うようになりました。
勿論、TopLink(とS2TopLink汗)がもっと安定版を出してからの話だとは思いますが。