エンティティをインタフェースではなくPOJOに
Seasarカンファレンスで発表してから2週間くらいたちますが、そのときもらった質問等を受けて、使い勝手を再考中です。
で、いろいろ考えた結果、エンティティをPOJOにすることにしました。理由はいくつかあるのですが、もっとも大きなものは、エンティティのすべてのプロパティをドメインクラスとして定義しなければいけないというのは、やっぱり大変すぎるからです。
新しい形式のエンティティはこうなります。
@Entity public class Employee { @Id int id; String name; Salary salary; // getter, setter }
まず、大きな変更点として、インタフェースではなくクラスです。次に、プロパティには基本的な値型(プリミティブ型含む)を使えます。オプションとしてSalaryのようなリッチなクラスも使えます。
S2DaoやS2JDBCのようにgetter/setterなしのpublicフィールドにすることもできます。(ただし、逆にprivateにはできなかったりします。パッケージプライベート以上の可視性が必要ということです)。
Salaryはこう。
@Domain(valueType = BigDecimal.class) public class Salary { private final BigDecimal value; public Salary(BigDecimal value) { this.value = value; } public BigDecimal getValue() { return value; } // 任意のメソッドを定義 }
特定のインタフェースを実装する必要はなく、@Domainをつければいいようにしました。
ポイントは、値はsetterではなくコンストラクタで設定するということです。つまり、不変オブジェクトとして定義できます!(あんまり気にする人がいないかもですが、個人的には重要ポイント)
これらの変更により、エンティティをPOJOなDTOに変換したりする機能などは不要になりました(エンティティやドメインがすでにPOJOなので)。他のフレームワークとも連携しやすくなりますね。
使い方としては、ドメインクラスをいっぱい作る使い方もOKですし、ドメインクラスをまったく使用しない(基本的な値型だけを使う)使い方もOKです。振る舞いも、ドメインクラスにもたせたりエンティティクラスにもたせたり、まったくもたせなかったりと自由です。
追記
サンプルコードがまちがっていた「public String getValue()」となっていたの直しました。