[Seasar-user:18797] 【Doma】 プリミティブ型の扱いについて

Ishikawa Hiromi [E-MAIL ADDRESS DELETED]
2009年 10月 28日 (水) 18:44:58 JST


中村(taedium)さん

はじめまして、石川と申します。
Doma を試用させていただいておりますが、非常に効率的に開発できてよくできているなあと思います。
その上で、試用していて気づいた事をいくつか書かせていただきます。

1.Daoでパラメータにプリミティブ型を使用した場合にエラーになる。
  以下のように、プリミティブ型(ラッパー型ではなく)をパラメータとするメソッドを定義すると、

    @Select
    Employee selectById(int id);

  以下のようなコードが生成されてしまいエラーになってしまいます。

    public example.entity.Employee selectById(int id) {
               - 略 -
        __query.addParameter("id", null.class, id);
                                                 ^^^^^^^^^^^

  たぶん、はなっからプリミティブを使っちゃダメということなのだと思いますが、コンパイラの出すエラーメッセージと原因が結びつかず、若干はまってしまいました。
 分かってしまえば何のことはなかったのですが、ここは改善していただけたらいいなと思いました。

2.Entityでプリミティブ型フィールドを定義して使用すると実行時エラーになる
  今度はEntityの方ですが、Entityのフィールドを以下のようにプリミティブ型で定義し、

    @Id
    @Column(name = "ID")
    int id;

  以下のようにこれを検索条件にしたDaoのメソッド(たとえば delete)

  -- メソッド定義部 --
      @Delete(sqlFile=true)
      int delete(Employee employee);

    -- sql ファイル --
    delete from Employee where id = /*employee.id*/0

  を定義すると、コンパイルは正常に終了しますが、実行時に以下のようなエラーになってしまい、ハマってしまいます。
  ここも改善していただけたらいいなと思います。

java.lang.AssertionError: Unfulfilled.
	at org.seasar.doma.internal.util.AssertionUtil.assertTrue(AssertionUtil.java:109)
	at org.seasar.doma.internal.wrapper.Wrappers.wrap(Wrappers.java:78)
	at org.seasar.doma.internal.jdbc.sql.NodePreparedSqlBuilder.wrap(NodePreparedSqlBuilder.java:498)
	at org.seasar.doma.internal.jdbc.sql.NodePreparedSqlBuilder.handleSingleBindVarialbeNode(NodePreparedSqlBuilder.java:220)
	at org.seasar.doma.internal.jdbc.sql.NodePreparedSqlBuilder.visitBindVariableNode(NodePreparedSqlBuilder.java:162)
	at org.seasar.doma.internal.jdbc.sql.NodePreparedSqlBuilder.visitBindVariableNode(NodePreparedSqlBuilder.java:88)
	at org.seasar.doma.internal.jdbc.sql.node.BindVariableNode.accept(BindVariableNode.java:88)
	at org.seasar.doma.internal.jdbc.sql.NodePreparedSqlBuilder.handleConditionalClauseNode(NodePreparedSqlBuilder.java:421)
	at org.seasar.doma.internal.jdbc.sql.NodePreparedSqlBuilder.visitWhereClauseNode(NodePreparedSqlBuilder.java:378)
	at org.seasar.doma.internal.jdbc.sql.NodePreparedSqlBuilder.visitWhereClauseNode(NodePreparedSqlBuilder.java:88)
	at org.seasar.doma.internal.jdbc.sql.node.WhereClauseNode.accept(WhereClauseNode.java:54)
	at org.seasar.doma.internal.jdbc.sql.NodePreparedSqlBuilder.visitFromClauseNode(NodePreparedSqlBuilder.java:371)
	at org.seasar.doma.internal.jdbc.sql.NodePreparedSqlBuilder.visitFromClauseNode(NodePreparedSqlBuilder.java:88)
	at org.seasar.doma.internal.jdbc.sql.node.FromClauseNode.accept(FromClauseNode.java:54)
	at org.seasar.doma.internal.jdbc.sql.NodePreparedSqlBuilder.visitAnonymousNode(NodePreparedSqlBuilder.java:140)
	at org.seasar.doma.internal.jdbc.sql.NodePreparedSqlBuilder.visitAnonymousNode(NodePreparedSqlBuilder.java:88)
	at org.seasar.doma.internal.jdbc.sql.node.AnonymousNode.accept(AnonymousNode.java:49)
	at org.seasar.doma.internal.jdbc.sql.NodePreparedSqlBuilder.build(NodePreparedSqlBuilder.java:132)
	at org.seasar.doma.internal.jdbc.query.SqlFileModifyQuery.prepareSql(SqlFileModifyQuery.java:65)
	at org.seasar.doma.internal.jdbc.query.SqlFileDeleteQuery.prepare(SqlFileDeleteQuery.java:30)
	at example.dao.EmployeeDaoImpl.delete(EmployeeDaoImpl.java:101)
	at example.DeleteTest.testDelete(DeleteTest.java:13)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at junit.framework.TestCase.runTest(TestCase.java:164)
	at junit.framework.TestCase.runBare(TestCase.java:130)
	at junit.framework.TestResult$1.protect(TestResult.java:106)
	at junit.framework.TestResult.runProtected(TestResult.java:124)
	at junit.framework.TestResult.run(TestResult.java:109)
	at junit.framework.TestCase.run(TestCase.java:120)
	at junit.framework.TestSuite.runTest(TestSuite.java:230)
	at junit.framework.TestSuite.run(TestSuite.java:225)
	at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

3.@Delegate について
 委譲先のメソッドから委譲元のメソッド(自動生成されたメソッドなど)を呼びたいケースが結構あると思います。
 その様なケースに対応するため、委譲元のインスタンスを委譲先から参照できるようにするとよいのではないでしょうか?

 ※ちなみに私は、上記のことを行うため、自動生成された Impl クラスを継承させて実装しましたが、せっかく自動生成されたメソッドをオー
  バーライドする形になるため、トレースログが出なくなるなど、デメリットを感じてしまいました。

4.プラグインに関して
 Dao のメソッド宣言部から、自動生成された実装クラスに飛ぶ機能があるいいなと思います。

今後実務で使わせていただこうと思っているので、ずうずうしいとは思いつつ書かせていただきました。
よろしくご検討願います。


Seasar-user メーリングリストの案内