Skip to content

Instantly share code, notes, and snippets.

@nakamura-to
Last active December 22, 2015 11:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nakamura-to/6464737 to your computer and use it in GitHub Desktop.
Save nakamura-to/6464737 to your computer and use it in GitHub Desktop.
Doma 1.34.0に入ったイミュータブルなエンティティのサポートについて

Doma 1.34.0に入ったイミュータブルなエンティティのサポートについて

概要

EXPERIMENTALな位置づけです。

JIRA

https://www.seasar.org/issues/browse/DOMA-297

Doma 1.34.0

http://www.seasar.org/wiki/index.php?SeasarWhatsNew%2F2013-09-19#s71b7bbb

説明

Entity

@Entityimmutable要素にtrueを指定してイミュータブルであることを示せます。 ポイントは以下の通りです。

  • 永続フィールドにはfinal修飾子が必要
  • コンストラクタのパラメータの型と名前は永続対象フィールドと一致しなければいけない
  • @OriginalStatesとの併用はできない
@Entity(listener = EmpListener.class, immutable = true)
@Table(name = "EMPLOYEE")
public class Emp {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @SequenceGenerator(sequence = "EMPLOYEE_SEQ")
    final Integer id;

    final String name;

    final int age;

    public Emp(Integer id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    ...
}

EntityListener

EntityListenerの中で新しいエンティティを生成し後続処理に反映させたい場合は、context.setNewEntity(newEmp)を呼びます。

public class EmpListener implements EntityListener<Emp> {

    @Override
    public void preInsert(Emp emp, PreInsertContext context) {
        Emp newEmp = new Emp(...);
        context.setNewEntity(newEmp);
    }

    ...
}

Dao

イミュータブルなエンティティを更新系のメソッドに渡す場合のポイントは次の通りです。

  • @Insert/@Update/@Deleteを注釈したメソッドの戻り値はorg.seasar.doma.jdbc.Result
  • @BatchInsert/@BatchUpdate/@BatchDeleteを注釈したメソッドの戻り値はorg.seasar.doma.jdbc.BatchResult
@Dao(config = AppConfig.class)
public interface EmpDao {

    @Insert
    Result<Emp> insert(Emp emp);

    @Update
    Result<Emp> update(Emp emp);

    @Delete
    Result<Emp> delete(Emp emp);

    @BatchInsert
    BatchResult<Emp> insert(List<Emp> emp);

    @BatchUpdate
    BatchResult<Emp> update(List<Emp> emp);

    @BatchDelete
    BatchResult<Emp> delete(List<Emp> emp);
}

補足

エンティティにlombokの@Valueを注釈して動作することを確認しています(Eclipseで確認)。

@Entity(listener = EmpListener.class, immutable = true)
@Table(name = "EMPLOYEE")
@Value
public class Emp {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @SequenceGenerator(sequence = "EMPLOYEE_SEQ")
    Integer id;

    String name;

    int age;
}

注意点

javacで実行すると、lombokとDomaのannotation processorの処理順序の問題で、上記のコードではうまく動きません。lombokの処理が先に動作することを期待しているからです。annotation processorでは処理順序を制御できません。

回避策として、次の2点を行ってください。

  • プロパティにfinalをつける
  • コンストラクタを作成する

この回避策により、lombokとDomaのannotation processorに依存関係がなくなります。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment