Cascadeのメモ
CascadeType.PERSIST, CascadeType.REMOVEの確認
MovieのCascadeTypeを次のように変更し、動作確認をしてみた。
cascade=CascadeType.ALL, ↓ cascade={CascadeType.PERSIST, CascadeType.MERGE},
CascadeExSample.class
package sample; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; public class CascadeExample { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("hibernate"); EntityManager em = emf.createEntityManager(); final EntityTransaction tx = em.getTransaction(); tx.begin(); Actor brad = new Actor("Brad Pitt"); Actor orlando = new Actor("Orlando Bloom"); Movie troy = new Movie("Troy"); troy.addActor(brad); troy.addActor(orlando); // Movie で CascadeType.PERSIST または CascadeType.ALL を定義している場合、 // Actor も登録される em.persist(troy); // Movie で CascadeType.REMOVE または CascadeType.ALL を定義していない為、 // Movieのみ削除される em.remove(troy); tx.commit(); em.close(); emf.close(); } }
実行結果
- cascade=CascadeType.ALL の場合
SELECT * FROM ACTOR ;
ID | NAME |
---|
SELECT * FROM MOVIE_ACTOR ;
MOVIE_ID | ACTOR_ID |
---|
SELECT * FROM MOVIE;
ID | NAME |
---|
- cascade={CascadeType.PERSIST, CascadeType.MERGE} の場合
SELECT * FROM ACTOR ;
ID | NAME |
---|---|
67 | Orlando Bloom |
68 | Brad Pitt |
SELECT * FROM MOVIE_ACTOR ;
MOVIE_ID | ACTOR_ID |
---|
SELECT * FROM MOVIE;
ID | NAME |
---|
CascadeType.REFRESHの確認
CascadeType.MERGE は、まぁ CascadeType.PERSIST と似たようなもんだろうということで、
CascadeType.REFRESH について少し動作を確認してみる。
CascadeType.REFRESH と fetch=FetchType.LAZY を併用した場合に EntityManager.find() では関連エンティティが取得されず、 EntityManager.refresh() を呼び出した場合のみ関連エンティティが取得されることを確認する。
CascadeRefreshExample.class
package sample; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; public class CascadeRefreshExample { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("hibernate"); EntityManager em = emf.createEntityManager(); final EntityTransaction tx = em.getTransaction(); tx.begin(); Actor brad = new Actor("Brad Pitt"); Actor orlando = new Actor("Orlando Bloom"); Movie troy = new Movie("Troy"); troy.addActor(brad); troy.addActor(orlando); em.persist(troy); tx.commit(); // EntityManagerをclose em.close(); // EntityManagerを再取得 em = emf.createEntityManager(); // fetch=FetchType.LAZY なのでMovieは取得しない System.out.println("####################################### find"); Actor brad2 = em.find(Actor.class, brad.getId()); System.out.println("############################################"); System.out.println("#################################### refresh"); // Actor で CascadeType.REFRESH または CascadeType.ALL を定義している為、 // Movieも取得される em.refresh(brad2); System.out.println("############################################"); em.close(); emf.close(); } }
実行結果
どうやら期待通りに動いてくれたらしい。
コンソールログ
####################################### find Hibernate: select actor0_.id as id0_0_, actor0_.name as name0_0_ from Actor actor0_ where actor0_.id=? ############################################ #################################### refresh Hibernate: select actor0_.id as id0_1_, actor0_.name as name0_1_, movies1_.actor_id as actor2_3_, movie2_.id as movie1_3_, movie2_.id as id1_0_, movie2_.name as name1_0_ from Actor actor0_ left outer join movie_actor movies1_ on actor0_.id=movies1_.actor_id left outer join Movie movie2_ on movies1_.movie_id=movie2_.id where actor0_.id=? ############################################