読書会(Java EE 7徹底入門)第5回議事録
[ 戻る ]
読書会(Java EE 7徹底入門)第5回議事録
=================================================
Java読書会BOF 「Java EE 7徹底入門」を読む会 第5回
=================================================
.. csv-table:: 開催概要
"日時", "2016年5月14日 10:00 - 17:00"
"場所", "川崎市教育文化会館 第3会議室"
"出席者(敬称略)", "伊藤、井上、今井、遠藤、加藤、小棚木、高橋(徹)、高橋(智)、根本、村山、吉本、川内(書記)"
議事
====
7.3 エンティティマネージャの基本
----------------------------
7.3.1 エンティティのライフサイクル
------------------------------
7.3.2 エンティティオブジェクトの作成と永続化
--------------------------------------
* MANAGEDやDETACHEDのエンティティに対するpersist操作は無視か例外発生とあるが、どっちなのか?
- (後日調査結果)JPA2.1(JSR-338)仕様書の3.2.2 Persisting an Entity Instance(P.81)に記載あり
+ MANAGEDエンティティに対するpersist操作は無視される
+ DETACHEDエンティティに対するpersist操作はEntityExistsExceptionかPersistenceExceptionが発生する
発生タイミング(persist呼び出し時かflush/commit時か)、どちらの例外が発生するかは仕様で決められておらず、実装依存
* エンティティがMANAGED状態か否かを調べる方法はあるか?
- EntityManagerのcontainsメソッドを利用する(コレクションフレームワークと同じ)
7.3.3 エンティティオブジェクトの取得と更新
-------------------------------------
* EntityManagerのfindメソッドにクラスオブジェクトを渡すのはなぜ?
- JPA実装がクラスのインスタンス化に利用しているかも
- メソッドの戻り値の型が、渡したクラスオブジェクトの型になり、キャストが不要
7.3.4 エンティティの削除
----------------------
7.3.5 デタッチ
-------------
7.4 クエリAPI
------------
7.4.1 パラメータ
--------------
7.4.2 サンプルデータ
------------------
7.5 JPQL
--------
* 箇条書きでは、SELECT節、FROM節と"節"となっているが、最後は、"それぞれの句の書き方"となっており、同じものを表しているのか?
- 7.5.1の"JPQL文の作成"に、"SELECT節(SELECT句からFROM句の直前まで)"(P.302)とあり、著者は何らかの使い分けをしている
7.5.1 JPQLの基本構文
-------------------
7.5.2 条件指定
-------------
"文字列の部分一致"セクション
------------------------
* "SELECT k FROM Knowledge k WHERE k.title LIKE :titleLike"の代わりに、
"SELECT k FROM Knowledge k WHERE k.title LIKE :titleLike%""と末尾にワイルドカードを付けることで、
クエリのパラメータ設定時側から、ワイルドカードを外すことができるか?(宿題)
"複数項目からの一致"セクション
--------------------------
* IN演算子を使うJPQLサンプルがパラメータ2個固定となっている(IN (:cat1, :cat2))が、利用しづらいので、
配列やリスト等可変長のパラメータを1つだけ渡す方法はないのか?(宿題)
- このような場合はCriteriaクエリを利用すればよいのでは?
+ (後日追記)Criteriaクエリのサンプルコードもパラメータ数固定の例で、参考にならず
"2つの数値の間"セクション
----------------------
* サンプルコードのJPQL文中、:fromのコロンとfromの間の空白は不要
* DateTimeFormatterを使用するのはなぜ?
- 23:59:59.999とミリ秒の単位で条件を指定するため
* 23.59.59.999と記載するぐらいなら、Betweenを使用せず、<や>の不等号を使えばよいのでは?
- 不等号の場合は2回評価が走るが、Betweenの場合は評価が1回で済む利点あり
"複数条件の指定"セクション
----------------------
* サンプルコード1〜2行目のjpql変数の初期化の箇所で、末尾のダブルクォーテーションが抜けている
7.5.3 取得結果の並べ替え
---------------------
* サンプルコードの更新日時項目名が、これまでのセクションのupdateDateからupdateAtに変更されている
* サンプルコードのStream#forEachメソッドがforeachと小文字になっており、誤り
- (後日確認結果)セクション7.5のサンプルコードは全て同様の誤りあり。一方セクション7.6は全てforEachと正しい
* 実行結果の表が3件となっているが、直後の本文の記載のとおり、4件が正しく、"JavaEEの実行環境"が漏れている。
7.5.4 エンティティの結合
----------------------
* (脚注19)RIGHT JOINは、直接SQLを記述する場合でも利用する機会はなく、JPQLで利用できなくても不都合なし
* P.315のサンプルコードのJPQL中の"FROM Knowledge k JOIN k.account a"の部分は、普通のSQLのJOINとは全く異なっている
- JQPLとSQLは似ている部分もあるが、異なる言語
- JOINの部分は差が大きい
7.5.5 フェッチ
-------------
"Lazyフェッチ"セクション
---------------------
* (図7.18)Lazyの場合のフェッチタイミングが、Listプロパティにアクセスした時点(2行目)ではなく、
List内の個々の要素にアクセスした時点(3行目)となっているが、本当?
- 本に記載されているとおり、Listプロパティにアクセスしただけでは不十分で、個々の要素にアクセスした時点ではないか
"N+1問題とJOINフェッチ"セクション
-----------------------------
* N+1問題の説明はこれで合っている?
1つのエンティティの、1対多のリレーション属性を取得する問題では?
- 本に記載されている説明(複数のエンティティをSELECTする際に、
リレーション属性の取得はエンティティ毎にクエリが発行される)で合っていると思う
* (図7.19)サンプルコードがEntityManagerのfindメソッド(=主キーによる1件取得)となっており、N+1問題の説明と合っていない
- 絵は図7.17や図7.18の絵と異なっており、絵の方が意図を表している
* サンプルコードのJPQL文は、JOINフェッチしたいリレーション属性(account a)がWHERE条件でも参照されている(a.id = :id)が、
このような場合は明示的にJOIN FETCHしなくとも、自動的にJOINしてくれないのか?
- JOIN FETCHの説明のサンプルコードなので、WHERE条件で参照されるリレーション属性であっても、
自動的にJOINされることはない(=FETCHするにはFETCH JOINが必要)のでは
* N+1問題のセクションの記述は疑問点も多く、関心のある方は各自で調べてください。
7.5.6 エンティティオブジェクトの集計
--------------------------------
* (集計関数の表)COUNT関数の戻り値の型がLongとなっており、覚えておく必要があるとしたら厳しい
* EntityManagerのcreateQueryメソッドで、戻り値の型パラメータはInteger、
JPQL文は"SELECT COUNT(foo.bar) FROM ..."としてクエリを作成、実行し、
結果をIntegerで受けるコードは、コンパイルは通るはずだが、実行できるか?(宿題)
7.5.7 名前付きクエリ
------------------
7.6 Criteria API
----------------
7.6.1 Criteria APIの基本構文
---------------------------
"Criteriaクエリの作成"セクション
-----------------------------
* CriteriaBuilder#createQueryメソッドのシグニチャのpublicとCriteriaQuery<T>の間にある<T>は??
- Foo.<Bar>boo(hoge)のようなメソッド呼び出し構文もある
* Criteriaクエリには、"結果として返されるエンティティの型","結果として取得したい式"を指定するとあるが、意味がわからない
- 続きを読めば分かるのではないか
* (脚注23)"7.5.2 条件指定で後述"となっているが、"7.6.2"の誤り
7.6.2 条件指定
-------------
* (P.329〜330)本文中の"equalsメソッド"は、"equalメソッド"の誤り
* 自動生成されたKnowledge_メタモデルクラスのソースコードでは、フィールドが初期化されていないが、これではnullとなるのでは?
- 実際には、JPA実装が裏で値を設定してくれるのではないか
* (関係演算子サブセクションの直前まで読んだ段階で)Criteriaクエリは、中間オブジェクトがごちゃごちゃと出てきて難しい
HibernateオリジナルのCriteriaクエリはもう少し分かり易かったように思う
c* サンプルコードのknowledge変数は、これまでのサンプルコードでのknowledgeRoot変数と同じと理解する
* サンプルコードでdescription属性が出てきているが、"7.4.2 サンプルデータ"セクション冒頭の図7.15には記載されていない
- "7.2 エンティティの基本"セクション冒頭のテーブルスキーマ図(図7.5)には、説明文カラムの記載あり
* 実行結果が1件のみ記載されているが、Javaで始まるナレッジは他に2件あり、漏れている。
7.6.3 取得結果の並べ替え
---------------------
7.6.4 エンティティの結合
---------------------
7.6.5 複数エンティティオブジェクトの一括取得
---------------------------------------
7.6.6 集計関数
-------------
* (脚注26)タプルの使い方は本書の対象範囲外とあるが、Criteriaクエリの説明は全て、
"前節のJPQLで説明のあった内容をCriteriaクエリで実現するするには"という説明になっており、
これを踏まえると、本書の対象範囲外とされているタプルは、JPQLにはない機能ということか?(宿題)
* サンプルコードにふってある、説明用の番号1〜3のうち、2と3が逆にふられている(本文は問題なし)
7.6.7 サンプル
-------------
* このセクションも、KnowledgeのRootオブジェクトの変数名がknowledgeとなっており、他のサンプルコードと相違している
- 他のサンプルコードとは相違しているが、全体のコードが示されている箇所で、
knowledgeの変数名で宣言、定義されており、このセクション内では整合している
8 データアクセス層の開発 - JPAの応用
--------------------------------
8.1 高度なエンティティの利用方法
----------------------------
8.1.1 フィールドに関する応用
-------------------------
"日時"セクション
--------------
* サンプルコードのフィールドの型はDate型となっているが、java.sql.Timestamp型はどこで出てくるのか?
- JPA実装がJDBCを使ってデータベースにアクセスする際には、java.sql.Timestamp型が用いられるということ
フィールドの型をDate型にした場合は、アプリケーションプログラマが直接java.sql.Timestamp型を使うことはない。
* java.sql.Timestampはナノ秒の精度があるが...
- Date型への変換の際に、切り捨てられるということだろう
"シーケンス"セクション
-------------------
* @SequenceGenerator注釈にinitialValue要素があり、サンプルコードでは1が指定されているが、
新規にテーブルを生成した直後はよいが、データを挿入後に、アプリケーションを再起動した場合は、どうなるのか?
- JPA単独では実現不可能と思われるため、JPA実装と利用するデータベース管理システムの両方に依存するのでは
(具体的な仕組みの調査は宿題)
- 主キー値の自動生成機能(@GneneratedValue注釈)は、内部の仕組みも分かった上で利用する必要がありそう
"複合ID"セクション
----------------
* @Embeddableの綴りは、これが正しい(P.354本文前半の綴りは誤り。本文後半と図8.3の綴りは問題なし)
"サロゲートキー"コラム
-------------------
* JPAを利用するとの立場からは、自然キーよりも代理キーの方が扱い易いのだろうが、
リレーショナルデータベース側の立場では、代理キーはアンチパターンとされている。
- Java読書会のメンバー間でも、自然キーと代理キーのどちらがよいか議論あり
8.2 ライフサイクルコールバック
--------------------------
* 表8.3のアノテーションが小文字で始まっている(@prePersist等)が、誤り(大文字で始まる)
* 検索したナレッジにコメントを追加した場合(ナレッジとコメントのリレーションは1対多で、カスケードするよう指定あり)、
以下のライフサイクルコールバック関数は呼び出されるか?(宿題)
- ナレッジの@PreUpdate, @PostUpdateコールバック
- コメントの@PrePersist, @PostPersistコールバック
.. note:: 次回は、P.357「8.3 エンティティクラスとテーブル構造」から。
[ 戻る ]