[Seasar-user:21655] Re: S2JDBC の AutoSelect への includes() と excludes() 実装

Koichi Kobayashi [E-MAIL ADDRESS DELETED]
2013年 7月 14日 (日) 04:30:00 JST


小林 (koichik) です.

ご存じの通り、S2JDBC 含めて Seasar2 に関しては

http://d.hatena.ne.jp/higayasuo/20080714/1216021595

「要望があれば小さな機能改善は行ないますが、大きな機能追加は行ないません。」

ということになっています。
なので、今回の要望が「小さな機能改善」なのか、
「大きな機能追加」なのかが問題になるのですが、
内容的には「小さな機能追加」なので微妙ですw
元々 INSERT/UPDATE に存在する機能ではあるんですよね。

どう判断します?>ひがさん


取り込むかどうかは別として、パッチを見て気になった点:
# 実際にパッチを適用して動かしたわけではなく、
# 眺めただけで書いてます。

・s2jdbc-it にもテストの追加が必要

・ドキュメントの「注意点」

> <code>excludes()</code>
> を指定して取得したインスタンスを更新に使用する場合、
> 更新時に同様の
> <a href="#指定したプロパティを更新対象から除外する">
>     <code>excludes()</code>
> </a>
> を指定しないと検索結果に含めなかったカラムがすべて空の値で更新されます。

excludes() だけでなく、includes() を指定した
場合も設定されないプロパティが存在しうるので、
上に

<code>includes()</code>
または

を追加。

・isTargetProperty()

@Id なプロパティを除外できちゃうのはまずいような。
ちゃんと動作するのかな? しない気がしないでもない。。。
特に対多な関連の場合とか。
@Id なプロパティは (関連先も含めて) 無条件に
includes 扱いにすべきかと思いますです。

あとこんなケース

List<Employee> results = 
    jdbcManager
        .from(Employee.class)
        .includes("id", "name", "department")
        .excludes("department.name")
        .leftOuterJoin("department")
        .leftOuterJoin("department.address")
        .getResultList();

department 以下は全部取得するけど name だけは
除外する、というケースで name が除外されなさそう。

パッチのテストケースでは excludes で関連を指定して
includes で個別のプロパティを指定しているケースは
ありますが、これはその逆のパターンでテストケースが
無いような気がします。

似たケースで、

List<Employee> results = 
    jdbcManager
        .from(Employee.class)
        .includes("id", "name", "department")
        .excludes("department.address")
        .leftOuterJoin("department")
        .leftOuterJoin("department.address")
        .getResultList();

department 以下は全部取得するけど address 以下は
除外する、というケースで address 以下が除外
されなさそう (fetch しなけりゃいいだろうという
話は置いておいて)。

前の例と同じ if 文で抜けてしまうのが原因ですが、
前の例の対策 (個別の excludes のチェックを先にする)
だけでは解決しないんじゃないかと。

department.address.xxx があった場合、いきなり
includes/excludes で指定された department.〜 で
始まるかチェックするのではなく、プロパティ名の
後ろから一つずつ要素を削って、まず department.address が
includes/excludes に含まれるか、次に department が
includes/excludes に含まれるか、というように、
プロパティ名の側を基準にチェックしないとダメじゃ
ないかと思いました (印象に過ぎませんが)。

関連を指定する機能は仕様的に少々危うい感じが
しないでもないです。


と書いてみると、コード量の割に落とし穴を作る可能性が
少なくない感じがしますね。。。


On Sat, 13 Jul 2013 23:22:21 +0900, Jun Futagawa <jfut @ integ.jp> wrote:

> S2JDBC のコミッタの皆さま
> 
> ふたがわ (jfut) です。
> 
> S2JDBC の AutoSelect が生成する select 句に、任意のカラム名のみを
> 生成可能にする includes() と excludes() を実装してみました。
> S2JDBC 本体へ取り込んでいただくことはできないでしょうか?
> 
> コードとドキュメントのパッチを添付ファイルにてお送りします。
> 足りないコードやドキュメントがあれば書きます。
> 
> 例として、
> 
> List<Employee> results = 
>     jdbcManager
>         .from(Employee.class)
>         .includes("id", "name", "department.name", "department.address.id")
>         .leftOuterJoin("department")
>         .leftOuterJoin("department.address")
>         .getResultList();
> 
> や、
> 
> List<Employee> results = 
>     jdbcManager
>         .from(Employee.class)
>         .excludes("id", "name", "department.name", "department.address.id")
>         .leftOuterJoin("department")
>         .leftOuterJoin("department.address")
>         .getResultList();
> 
> といった指定で、指定したプロパティ以外は検索結果に含まれなくなります。
> これにより、データベースから転送されるデータ量やJVMのメモリ使用量を
> 減らすことができます。 
> 特に、たくさんネストして結合するものの、参照する必要がないプロパティが
> ある時などに有用だと思います。
> 
> よろしくお願いします。
> 
> -- 
> Jun Futagawa


-- 
{
  name: "Koichi Kobayashi",
  mail: "koichik @ improvement.jp",
  blog: "http://d.hatena.ne.jp/koichik/",
  twitter: "@koichik"
}



Seasar-user メーリングリストの案内