DomaでSerializableなオブジェクトを永続化したり取得したりするには
たとえば、次のクラスのオブジェクトをテーブルにシリアライズしたいとします。
public class Person implements Serializable { private static final long serialVersionUID = 1L; public String name; public Person(String name) { this.name = name; } }
テーブルの定義はこうします。VARBINARYに入れます。
create table hoge ( id integer not null primary key, person VARBINARY(1024) )
テーブルに対応するエンティティクラス。personカラムに対応するJavaの型はPersonではなくPersonHolderにするのがポイント。そしてPersonのgetter/setterでは、personHolderから取得したりpersonHolderに設定したりします。
@Entity public class Hoge { @Id int id; @Column(name = "person") PersonHolder personHolder = new PersonHolder(); public int getId() { return id; } public void setId(int id) { this.id = id; } public Person getPerson() { return personHolder.getPerson(); } public void setPerson(Person person) { personHolder.setPerson(person); } }
PersonHolderはドメインクラスにします。@Domainをつけるのがポイント。Personのsetterやgetterでシリアライズやデシリアライズします。
@Domain(valueType = byte[].class) public class PersonHolder { private byte[] bytes; private Person person; public PersonHolder() { } // ResultSet.getBytes(int)で取得された値がこのコンストラクタで設定される PersonHolder(byte[] bytes) { this.bytes = bytes; } // PreparedStatement.setBytes(int, bytes)へ設定する値がこのメソッドから取得される byte[] getValue() { return bytes; } public void setPerson(Person person) { if (person != null) { this.bytes = SerializableUtil.serialize(person); } this.person = person; } public Person getPerson() { if (person != null) { return person; } if (bytes != null) { person = (Person) SerializableUtil.deserialize(bytes); } return person; } }
こんな感じで永続化したり取得したりします。
Hoge hoge = new Hoge(); hoge.setId(1); hoge.setPerson(new Person("SMITH")); HogeDao dao = new HogeDaoImpl(); dao.insert(hoge); hoge = dao.selectById(1); assertEquals("SMITH", hoge.getPerson().getName());
Person自体をドメインクラスにし、Person全体ではなく必要なプロパティだけをシリアライズしてもいいかもしれません。その場合は、PersonHolderというクラスはいらなくなります。