S2EJB3Unitを使ったpersistの検証

IDを自動生成する設定でEntityをpersistした場合、生成されるIDを期待値としてあらかじめExcelに用意できないのでS2Unitのreloadメソッドを使ってテストができないですね、という話が Seasar Conference 2006 Spring のときにありました。(S2Unitのreloadメソッドはプライマリキーを使ってDBから値をリロードします。)

S2EJB3Unitで対策を考えてみました。EntityをpersistしてEntityManagerをflushすればEntityにIDが書き戻されるはずなのでこの値を使ってリロードするようにしてみました。こんな感じでどうでしょう。
まず、期待値と結果値をExcelで用意します(DEPARTMENT - EMPLOYEE - ADDRESS といったテーブル構造を想定してます)。[]でくくったのはExcelのシート名です。ポイントは期待値のシートにIDのカラムを含めないことです(単にIDは比較しないということです)。

insertEmployeePrepare.xls
[ADDRESS]

ID CITY
3 京都

[DEPARTMENT]

ID DEPARTMENTNAME
2 経理


insertEmployeeResult.xls
[EMPLOYEE]

EMPLOYEENAME SALARY DEPT_ID ADDRESS_ID
XXX 3000 2 3


次に、テストメソッドを書きます。ポイントはreloadAsDataSetメソッドを使ってエンティティをDataSetとして再取得するところです。EntityManagerのflushはreloadAsDataSetメソッドの中で実行してます。

public class EmployeeTest extends S2EJB3TestCase {
  @Rollback
  public void testInsertEmployee() {
    readXlsWriteDb("insertEmployeePrepare.xls");
    DataSet expected = readXls("insertEmployeeResult.xls");
    
    Address address = getEntityManager().find(Address.class, new Long(3));
    Department department = getEntityManager().find(Department.class, new Long(2));
    Employee employee = new Employee();
    employee.setEmployeeName("XXX");
    employee.setSalary(3000);
    employee.setAddress(address);
    employee.setDepartment(department);
    getEntityManager().persist(employee);
    
    assertEquals("1", expected, reloadAsDataSet(employee));
  }
}

ひとつのテーブルに対して複数件insertされる場合の検証は特に考えていません(テストには必要ないと思いました)。
ただ、SecondaryTable、Joined Sublcassなどを使ったエンティティをpersistすると同時に複数テーブルにinsertが実行されることがありますが、これを検証したいことはあると思います。その場合は期待値のExcelシートを検証したいテーブルの数だけ用意しておけばOKです。カスケードで関連先のエンティティも同時にpersistされることを検証したい場合は reloadAsDataSet(employee, true) としてリレーションシップも辿ることを示して、期待値のExcelシートをテーブルの数だけ用意します。

(追記)
reloadAsDataSet なんていうメソッド作らなくても EntityManager を flush した後に エンティティを refresh すればいいのかも。DBにinsertしたデータをJDBC APIで取得するかJPAで取得するかのちがいなんですよね。
id:koichikさん、id:da-yoshiさん、つっこみどころがあったらよろしくお願いします。