持続性コンテキスト


Java ORM標準JPAプログラム講座

単純な例


@Columnの挿入可能なプロパティをテストするときに、永続的なコンテキストに関連する例を作成します.
カリキュラムの例と似ているが発生する問題を解決することで、永続的なコンテキストを理解できます.

メンバー・オブジェクト

@Entity
public class Member {
    @Id
    private Long id;

    @Column(name = "name",insertable = false)
    private String username;

    private Integer age; //Integer와 가장 적합한 데이터타입이 설정된다.

    @Enumerated(EnumType.STRING)
    private RoleType roleType; //DB에는 Enum이 없음 -> Enumnerated

    @Temporal(TemporalType.TIMESTAMP)
    private Date createdDate; //날짜와 같은 속성일 때는 Temporal

    @Temporal(TemporalType.TIMESTAMP)
    private Date lastModifiedDate;

    @Lob
    private String description; //varchar을 넘어서는 텍스트 정보를 넣고 싶으면 Lob을 사용한다.

    public Member(){
    }

    public Member(Long id, String username) {
        this.id = id;
        this.username = username;
    }
    
	public void getUsername() {
        return username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
}

1.保存後の変更値

 public static void main(String[] args) {
        //persistence unit name을 적어야 한다.
        EntityManagerFactory enf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = enf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        //code
        try {
            Member member1 = new Member(154L, "AAA");
            Member member2 = new Member(164L, "BBB");

            em.persist(member1);
            em.persist(member2);
            member1.setUsername("Change");

            System.out.println(em.find(Member.class,154L).getUsername());

            System.out.println("================================");
            tx.commit();
        }catch(Exception e){
            tx.rollback();
        }finally {
            em.close();
        }
        enf.close();
    }
=>insertクエリーはupdateクエリーとともに表示されます.
非永続状態
Member member1 = new Member(154L, "AAA");
Member member2 = new Member(164L, "BBB");
永続状態
em.persist(member1);
em.persist(member2);
=>は、プライマリ・キャッシュおよび書き込み遅延のSQLリポジトリに格納されます.
usernamのinsertableクエリーログセクションで説明
永続状態-変更を検出
member1.setUsername("Change");
=>永続性コンテキストでmember 1の変更を検出し、遅延書き込みのSQLストレージでupdate文を発行します.
System.out.println(em.find(Member.class,154L).getUsername());
永続性コンテキストを管理するエンティティマネージャ(member 1を直接インポートするのではなく)にオブジェクトをインポートし、名前を出力すると、「Change」として出力されます.
トランザクションのコミット-リフレッシュ
tx.commit();
トランザクションのコミット時にリフレッシュが発生します.
JPAから更新
  • 永続コンテキストの変更をDBに反映します.
  • 書き込み遅延SQLリポジトリのクエリーを一度に送信します.
  • は、永続性コンテキストをクリアするのではなく、同期するための概念です.
  • コンソール-クエリー
    Hibernate: 
        /* insert hellojpa.Member
            */ insert 
            into
                Member
                (age, createdDate, description, lastModifiedDate, roleType, id) 
            values
                (?, ?, ?, ?, ?, ?)
    Hibernate: 
        /* insert hellojpa.Member
            */ insert 
            into
                Member
                (age, createdDate, description, lastModifiedDate, roleType, id) 
            values
                (?, ?, ?, ?, ?, ?)
    Hibernate: 
        /* update
            hellojpa.Member */ update
                Member 
            set
                age=?,
                createdDate=?,
                description=?,
                lastModifiedDate=?,
                roleType=?,
                name=? 
            where
                id=?
    Insert文が終了するとupdate文が作成されます.

    1番の例題の特殊点は?

  • メンバーのユーザー名はinsertable=false、
  • です.
  • メンバー=新規メンバー(id値、username)の場合
  • Member member1 = new Member(154L, "AAA");
    Member member2 = new Member(164L, "BBB");
    
    em.persist(member1);
    System.out.println(em.find(Member.class,154L).getUsername());
    em.persist(member2);
    persist後、メンバー1のユーザ名を出力すると「AAA」が表示されます
    永続性コンテキストでは、プライマリキャッシュは同時に「AAA」を格納するためです.
    でもDB見たら?

    AAA値がないことを確認できます.
    tx.commit();
    System.out.println(em.find(Member.class,154L).getUsername());
    トランザクションのコミット後に出力を試行しても、プライマリキャッシュからオブジェクト値が取得されるため、「AAA」が出力になります.
    null出力を正しく受信するには、次の手順に従います.
    em.detach(member1);
    
    System.out.println(em.find(Member.class,154L).getUsername());
    これを準永続状態に設定し、DBに再インポートしますが、null値が正しいかどうかを判断できます.

    整理1号例

  • insertableはほとんど使わないと言っていました!
  • の持続性コンテキストに影響するカラムは、挿入時に注意してください.
    =>この言葉は不自然です.usernameを挿入するときはusernameを付けず、オブジェクトを作成するときはusername値を加えているので、オブジェクトを作成するときにusername値を付けない方向に実現します.
  • 2.値変更後の永続化

    Member member1 = new Member(154L, "AAA");
    Member member2 = new Member(164L, "BBB");
    member1.setUsername("Change");
    
    em.persist(member1);
    System.out.println(em.find(Member.class,154L).getUsername());
    
    例題1はこれが自然な例であることを知った.
    Member member1 = new Member(154L, "AAA");
    Member member2 = new Member(164L, "BBB");
    member1.setUsername("Change");
    これらのセクションは非永続的な状態にあるため、永続性コンテキストには影響しません.
  • もコンソールウィンドウに「変更」と表示されますが、実際のデータベースには空の値
  • が含まれています.
    コンソール-クエリー
    Hibernate: 
        /* insert hellojpa.Member
            */ insert 
            into
                Member
                (age, createdDate, description, lastModifiedDate, roleType, id) 
            values
                (?, ?, ?, ?, ?, ?)
    Hibernate: 
        /* insert hellojpa.Member
            */ insert 
            into
                Member
                (age, createdDate, description, lastModifiedDate, roleType, id) 
            values
                (?, ?, ?, ?, ?, ?)
    非永続状態では値が永続状態になるため、update文は消えません.
    コード#コード#
     Member member1 = new Member(154L, "AAA");
    Member member2 = new Member(164L, "BBB");
    member1.setUsername("Change");
    
    Member findMember = em.find(Member.class, 154L);
    System.out.println(findMember);
    非永続状態でfindを実行すると、プライマリキャッシュには値がありません.
    クエリはすぐに失敗し、findMemberはnull値を返します.
    これは、挿入性テストで永続性コンテキストを復習した例です.