読書会(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 エンティティクラスとテーブル構造」から。


[ 戻る ]