[JPA]管理とエージェントの関連付け
18898 ワード
第8章
オブジェクトは、オブジェクトシェイプを使用して関連するオブジェクトを参照します.ただし、オブジェクトはデータベースに格納されているため、関連オブジェクトを思う存分閲覧することは難しい.JPAインプリメンテーションはエージェント技術を用いてこの問題を解決する.
8.1エージェント(Proxy)
프록시 객체
8.1.1エージェントインフラストラクチャ
// Persistence Context 에 Entity가 없으면 데이터베이스를 조회
// 엔티티를 사용하지 않아도 데이터베이스를 조회함
Member member = em.find(Member.class, "member1");
// 엔티티를 직접 사용하는 시점까지 데이터베이스 조회를 미룸
Member member = em.getReference(Member.class, "member2");
プロキシオブジェクトのフィーチャー
한 번만 초기화
프록시가 엔티티로 바뀌는 것이 아니다!!
target
値で埋めます.instance of
使用-類型比較)em.getReference()
エージェントではなく実際のエンティティを呼び出します.반대로,
初期프록시로 조회
em.find()とクエリを行うと、エンティティオブジェクトではなくエージェントオブジェクトが返されます!a == :a
!영속성 컨텍스트
の助け.プロキシ初期化
エージェントの初期化は
영속성 컨텍스트
で行われる.実際に使用すると、プロキシオブジェクトの初期化と呼ばれるデータベースをクエリーして実際のエンティティオブジェクトを作成します.
//Meber Proxy를 반환한다.
Member member = em.getReference(Member.class, "id1");
member.getName();
Member member = em.getReference...
transaction.commit();
em.close(); // 영속성 컨텍스트 종료
member.getName();
//결과
org.hibernate.LazyInitializationException 예외 발생 !
プロキシ初期化の検証
org.hibernate.Hibernate.initialize(entry);
JPA표준은 강제 초기화가 없음
、強制コール:member.getName() エージェントと識別子
Team team = em.getReference(Team.class, "team1"); // 식별자 보관
team.getId(); // 초기화되지 않음
boolean isLoad = PersistenceUnitUtil.isLoaded(entity);
// 프록시 인스턴스 초기화 여부 확인
8.2即時ロードと遅延ロード
即時ロード(緊急)
@Entity
public class Member {
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name= "TEAM_ID")
private Team team;
// ...
}
Member member = em.find(Member.class,"member1");
Team team = member.getTeam();
// SQL
SELECT *
FROM
MEMBER M LEFT OUTER JOIN TEAM T
ON M.TEAM_ID=T.TEAM_ID
WHERE
M.MEMBER_ID = 'member1';
外部結合に比べて、内部結合はパフォーマンスの最適化に役立ちます.内部結合を使用するために、外部キーにNOT NULL制約を設定すると、値が保証されます.
@JoinColumn(name="TEAM_ID", nullable=false)
明示されているように、内部結合が使用されます.または
@ManyToOne(fetch = FetchType.EAGER, optional = false )
@JoinColum(name ="TEAM_ID")
private Team team;
</br>
### 지연 로딩(lazy)
``` java
Member member = em.find(Member.class,"member1");
Team team = member.getTeam(); // 프록시 객체
team.getName(); // 팀 객체 실제 사용
1.コレクションの即時ロードでは、常に外部結合が使用されます.
2.コレクションをすぐにロードすることは推奨されません.
≪即時ロード|Immediate Load|emdw≫:≪遅延ロードのクリア|Clear Deferred Load|emdw≫
8.4永続的移行:CASCADE
あるエンティティを永続状態にしたい場合は、関連するエンティティも一緒に永続状態にしたい場合は、
영속성 전이기능
を使用します.JPAはCASCADEオプションで、永続的な変換を提供します.簡単に言えば、永続性遷移を使用する場合、親エンティティをアセンブリする際に、サブエンティティを一緒に格納することもできる.@Entity
public class Parent {
@OneToMany( mappedBy = "parent", cascade = CascadeType.PERSIST )
private List<Child> children = Lists.newArrayList();
}
private static void save(EntityManager em) {
Parent parent = new Parent();
child1.setParent(parent);
child2.setParent(parent);
parent.getChildren().addAll(child1,child2);
em.persist(parent);
}
Parent findParent = em.find(Parent.class, 1L);
em.remove(findParent);
부모 Entity
外来鍵制限条件により発生외래키 무결성 예외
8.5孤立オブジェクト
JPAは、親エンティティに関連付けられていない子エンティティを自動的に削除する機能を提供し、孤児オブジェクトの削除(ORPHAN)と呼ばれています.
//엔티티
@OneToMany(mappedBy = "parent", orphanRemoval = true)
private List<Child> children = new ArrayList<>();
// 코드
Parent paren = em.find(Parent.class, parentId);
parent.getChildren().remove(removeObject);
8.6永久転移+孤児対象、ライフサイクル
CascadeType.All+孤児Removal=trueを併用すると?
저장
親に登録するだけ.(CASCADE) Parent parent = em.find(Parent.class, parentId);
parent.addChild(child1);
삭제
親から外しておけばいい.(OrphanRemoval) Parent parent = em.find(Parent.class, parentId);
parent.getChildren.remove(removeObject);
Reference
この問題について([JPA]管理とエージェントの関連付け), 我々は、より多くの情報をここで見つけました https://velog.io/@dbwlgns98/JPA-프록시와-연관관계-관리テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol