[JPA/金英漢]永続性とは?


この文章は金英漢のJPA講義の3章を聞いてまとめたものだ.
レッスン:Java ORM標準JPAプログラミング-基本編
教材:Java ORM標準JPAプログラミング🤷‍♀️

Jpaの中で2つ重要なのは?

  • クライアント対デバイスマッピング
  • 持続コンテキスト
  • この章では、最も重要な2つの永続的なコンテキストについて説明します.

    n「持続性」コンテキストは


    :エンティティを永続的に保存する環境;論理概念
    :アプリケーション-データベース間でオブジェクトを格納する仮想データベースロール(→リフレッシュ時にデータベースに反映)
    エンティティマネージャとしての永続性コンテキストへのアクセス(J 2 SEでは1:1の関係、SpringBootではN:1)
    これを使う理由は?バッファまたはキャッシュに使用!

    <エンティティのライフサイクル4種類>

  • 非永久状態(new/transient)
  • オブジェクトのみを作成し、エンティティにXを関連付ける
  • にマッピングする永久状態(管理)→@Idのキー値
  • が必要である.
    オブジェクトを作成して保存しました.
    永続性コンテキスト管理エンティティ(プライマリキャッシュ/ライト遅延リポジトリ)
    ex) em.persist(member);
    //객체를 생성만 한 상태(비영속)
    Member member = new Member();
    member.setId("member1");
    EntityManager em = emf.createEntityManager();
    em.getTransaction().begin();
    
    //객체를 저장한 상태(영속)
    em.persist(member);
  • 準永久状態(分離)
  • エンティティは永続的なコンテキストでex)em.detated()を分離します.
  • 削除状態
  • エンティティex)em.remove()を削除します.

    など、ステータス変更は大きく分けて2つに分けられます。

  • 非永久→永久→削除
  • 英速→準英速

  • 👍 永続性コンテキストの利点


    1.メインキャッシュ


    エンティティの問合せ時
  • プライマリキャッシュクエリ
  • から
  • プライマリ・キャッシュにない場合、データベースはクエリー(プライマリ・キャッシュを保存して返す)
  • を返します.
    EMはトランザクションユニットであるため、トランザクションが完了するとメインキャッシュもクリアされる
    ◇最初のキャッシュはより高い性能を有するが、機械化のメリットが大きい
    (ちなみに、セカンダリキャッシュはアプリケーション全体が共有するキャッシュです)

    2.永続エンティティの一貫性の確保→メインキャッシュ

    Member a = em.find(Member.class, "member1");
    Member b = em.find(Member.class, "member1");
    
    System.out.println(a == b) // 동일성 보장
    同じ呼び出しを繰り返すと、プライマリ・キャッシュ内の同じエンティティが返され、一貫性が確保されます.
    (MybatisはJPAをサポートしていません)
    注-JPA 同一性保障の問題?
    (データベース・レベルではなくアプリケーション・レベルでトランザクション・アイソレーション・レベルを指定)→16.1

    3.エンティティ登録時:書込み遅延


    トランザクションのコミット時→一度にデバイスにSQLを送信
    その前に、遅延書き込みSQLリポジトリに入れて、一度に送信します!(パフォーマンスのため)
    EntityManager em = emf.createEntityManager();
    EntityTransaction transaction = em.getTransaction();
    //엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다.
    transaction.begin(); // [트랜잭션] 시작
    em.persist(memberA);
    em.persist(memberB);
    
    //여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
    //커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
    transaction.commit(); // [트랜잭션] 커밋

    4.エンティティの変更時:変更の検出(ダーティ処理)


    開発者は、変更時に個別に更新または保存する必要はありません.
    EntityManager em = emf.createEntityManager();
    EntityTransaction transaction = em.getTransaction();
    transaction.begin(); // [트랜잭션] 시작
    // 영속 엔티티 조회
    Member memberA = em.find(Member.class, "memberA");
    // 영속 엔티티 데이터 수정
    memberA.setUsername("hi");
    memberA.setAge(10);
    
    //em.update(member) 이런 코드가 없어도 된다!
    transaction.commit(); // [트랜잭션] 커밋
    内部の動作原理から見ると、
    リフレッシュポイントでエンティティとスナップショットを比較して、置換されたエンティティを検索します.
    代替エンティティがある場合→更新クエリーを遅延書き込みリポジトリに保存→デバイスに反映

    5.遅延ロード=8章で詳しく説明する


    💫 リフレッシュすると~?


    :永続性コンテキストの変更をDBに同期します(名前はX、削除ではありません!)
    *メソッド:em.flush()を直接呼び出すか、トランザクションまたはJPQLをコミットします.

    リフレッシュが発生した場合

  • 変更検出
  • 遅延書き込みされたSQLリポジトリに
  • 修正エンティティ
  • を登録
  • リポジトリ内の集約クエリーは、データベース
  • に一度に送信される.
    最初のキャッシュに関連するXは、遅延書き込みストレージをデバイスに反映するプロセスです!
    このメカニズムは、トランザクションのコミット前に同期するだけで実現できます.
    ? 后で勉强します!トランザクションと永続性コンテキストのサイクルを調整することが重要です.
    注:事務とは?DBの状態変化作業ユニット(開発者決定)

    ❗必要に応じて準零速状態にすることができる→後補充


    :永続状態にあるエンティティを永続コンテキストからem.depect()から分離します.
    準永続状態とは、プライマリ・キャッシュおよびライト遅延のSQLストレージから削除された状態です.
    *つまり、トランザクションのコミット時にクエリーを生成できません
    永続状態とは、JPAが管理する状態、メインキャッシュの状態ex)em.persist()em.find()

  • em.detach(entity)
    :特定のエンティティのみを準永続状態に変換

  • em.clear()
    :プライマリ・キャッシュを消去します.これにより、永続コンテキストが最初から作成されます.
    ◇テストケースを確認するときに、クエリは最初から作成され、確認に役立ちます

  • em.close()
    :永続性コンテキストをオフにしてXを管理します.データは変更されません.