currvalを取得するコードをAbstractServiceに追加してみた

ヘッダ・ディテールタイプのテーブル構成、たとえば、見積と見積明細のようなテーブル構成の場合、「見積明細」側に見積IDを設けて、リレーションを構成することになる。

そして、見積データをデータベースに挿入する際には

  1. 見積テーブルに親行を挿入
  2. 見積明細テーブルに子行(明細行)を挿入

という手順となる。明細行挿入の際に、親行のIDがわかっておく必要がある。IDをどう発番しているかにもよるが、シーケンスをつかって発番している場合は、insert後、RDBMSにもよるが、

  select seq_name.currval from dual;

  select currval('seq_name');

ということをする。

で、S2JDBCでもこういうことをしたかったので、AbstractServiceに追加してみた。動作確認は、Postgresqlでしかやってませんが・・・

public abstract class AbstractService<ENTITY> extends
S2AbstractService<ENTITY> {

  /**
   * 前提:nextval があらかじめ呼び出されていること
   */
  public long getCurrentId() {

    JdbcManagerImplementor jdbcManagerImplementor = ((JdbcManagerImplementor) this.jdbcManager);
    DbmsDialect dialect = jdbcManagerImplementor.getDialect();
    EntityMetaFactory entityMetaFactory = jdbcManagerImplementor
        .getEntityMetaFactory();
    EntityMeta entityMeta = entityMetaFactory.getEntityMeta(entityClass);

    String tableName = entityMeta.getTableMeta().getName();

    String currvalSql = dialect.getIdentitySelectString(tableName, "ID");

    return jdbcManager.selectBySql(Long.class, currvalSql).getSingleResult();
  }
}

追記

Dialectの実装を見る限り、OracleMysqlは対応してないっぽい。メジャーどころではPostgresqlくらいなのかな。