EJB 3.0(Public Draft)入門記 Java Persistence API Chapter4 その10

EJB QLの戻り値の型とかバルク更新/削除とかNull値とかEJB QLの制限とかについてです。

4.10 Return Value Types

クエリのSELECT節の結果で返される型には次のようなものがあります。いままでのまとめみたいなものですね。

  • エンティティの抽象スキーマ
  • ステートフィールド型
  • 集計関数の結果
  • コンストラクタ操作の結果 (SELECT NEW節を使うやつね)
  • 上に挙げたもののいくつかの組み合わせ

あとはEJB 2.1に固有の話みたい、ということでとばしちゃいます...。

4.11 Bulk Upudate and Delete Operations

バルク更新と削除は単一のエンティティに対して(サブクラスがあればそのサブクラスも一緒に)適用されます。たったひとつのエンティティ抽象スキーマ型だけをFROM節やUPDATE節に指定できるようです。削除は指定されたクラスとそのサブクラスにたいしてだけ行われて関連のエンティティにはカスケードしないそうです。更新の場合、新しくセットする値は適用されるステートフィールドの型と互換性がなければいけないとのことです。更新、削除ともこんな感じです。WHERE節をつけることもできます。

update Product p set p.price = p.price * 1.05
delete from LineItem l where l.quantity < 20

バルク更新/削除を使うにあたって注意しなければいけないことがあります。それはバルク更新/削除によって永続コンテキストにアクティブなエンティティとデータベースの間で不整合が起きるかもしれないからです。一般的に、バルク更新/削除は次のどちらかの方法で行われるべきだそうです。

どうやらバルク更新/削除って永続コンテキストを見ないでデータベースにクエリを直接発行するみたいです。

1番目の方法は問題ないはずです。2番目の方法は永続コンテキストのタイプがトランザクションであることが前提だと思います。トランザクション開始時点では永続コンテキストにはエンティティが存在しないのでバルク更新/削除によって永続コンテキスト内のエンティティとデータベースで整合性が崩れることはあり得ないのですね。

4.12 Null Values

ここはNullとかunknownとかの話ですね。このあたりちゃんと理解できていないんですよね。

参照のターゲットがデータベースに存在しない場合、値はNULLだとみなされます。SQL92のNULLのセマンティクスがNULLを含んだ条件式の評価について定義しているそうです。
それらを簡単にまとめるとつぎのようになるそうです。

  • NULL値との算術演算は常にunknown値を生み出す。
  • 2つのNULL値は等しいとみなされない。NULL同士の比較はunknown値を生み出す。
  • unknown値との比較や算術演算は常にunknown値を生み出す。
  • Boolean演算子は3値論理を使う。

とっつきにくいですが4つだけのルールと考えればそう難しくもないかな。とっつきにくいといえば、このルールよりもtrue AND unknowがunknownになるとかの定義ですね。これが何でかよくわからんのです。なんかいい覚え方ないかなぁ。あとで思い出しやすいように定義の表ものっけておこう。true AND unknow と false or unknown が unknownになることに注意しろって何かに書いてあったような気がします。何だっけ。とにかくそれだけ覚えとけばなんとかなるかも。

AND T F U
T T F U
F F F F
U U F U
OR T F U
T T T T
F T F U
U T U U
NOT
T F
F T
U U


NullやunknownについてEJB QLは基本的にSQLと同じ考え方をするということですね。しかし、EJB QLはSQLを抽象化した言語のはず。リレーショナルデータベース以外の他の永続ストアの言語でもNullとかunknownとかの考え方はつうじるのかなぁ?

4.13 Equality and Comparison Semantics

EJB QLは似たような型(like type)同士の値が比較されることを認めています。ある型が他の型と似ているとは、同じJavaの型に対応しているか、または一方がプリミティブ型で他方が対応するラッパーであったりすることをいうそうです。似たような型同士で比較できるというルールにはひとつだけ例外があって、numeric promotionのルールに従って数値同士の比較も認められているらしいです。numeric promotionのルールっていうのはintとlongの比較ではintはlongとして比較されるっていうやつでしょうか?

同じ抽象スキーマ型の2つのエンティティはそれらがおなじプライマリキーを持っているときだけ等しいらしいです。

4.14 Restrictions

EJB QLにはいくつか制限があるそうです。

  • SQLは固定小数の算術演算のサポートを要求しているが、EJB QLはサポートしない。
  • Booleanの比較は = と <> に制限されている。
  • EJB QLはコメントをサポートしない。

1番目の固定小数の算術演算のサポートをしないっていうのはそういう計算はEJB QLじゃなくてJavaでやれってことでしょうか?
2番目の意味するところは!= は使えないってことかな。
3番目のやつは、別にSQLと同じコメントあってもいいじゃんと思いますけど、どうなんでしょ。

4.15 Examples

ここに挙がっている例はだいたい試したような気がします。

4.16 EJB QL BNF

リファレンスです。


やた、Chapter4 終わりだー。なんか最後のほうは終わらせることを目的で書いてしまった感がありますが...、まぁそういうときもあるよね。
しかし、やっと94ページまでこれました。このあたりが、Java Persistence APIのドキュメントのちょうど折り返し地点です。finalリリースまでに入門記を終わらせることができるかなぁ。まあ、finalが出たら出たで、そっちにあわせればいいか。