Hibernateマルチペアマルチ削除の問題


Hibernateは多対多の例が多いが、よく見ると、多くは保存されており、削除談は少ないが、問題は少なくないので、簡単にテストしなければならない.以下、簡単な多対多関係を構築する.
先生TeacherとカリキュラムCourseは多対多の関係です.
まず、データベースにレコードを挿入します.
public void testSave() {
		Session session = HibernateSessionFactory.getSession();
		session.beginTransaction();

		// create course
		Course c1 = new Course();
		Course c2 = new Course();
		c1.setName("C");
		c2.setName("Java");

		// create teacher
		Teacher t1 = new Teacher();
		Teacher t2 = new Teacher();
		t1.setName("Leo");
		t2.setName("Rose");

		// create relationship
		c1.getTeachers().add(t1);
		c1.getTeachers().add(t2);
		t1.getCourses().add(c1);
		t2.getCourses().add(c1);

		/*           save-update,     none,             ,      */
		//session.save(t1); 
		//session.save(t2);
		session.save(c1);

		session.getTransaction().commit();
		session.close();
	}

テストの結果は次のとおりです.
1.cascadeがマスタセットにしても被マスタセットにしてもallにしても、deleteなどがdeleteカスケード削除に関係していれば、両端および中間テーブルのレコードが削除されることが多いので、通常はこのような必要は少ないので、このような場合はallに簡単に設定すれば、deleteは関係および両端のレコードを簡単に削除することができます.
2.ある一方のレコードおよび中間のテーブルの関連情報のみを削除したい.このような需要は通常よく見られる.このときcascadeの設定はdeleteに関連するカスケード制約を除く.以下は削除の心得です.
削除されたレコードがプライマリ・コントローラである場合、このレコードを簡単に削除するだけで、カスケード関係とプライマリ・コントローラのレコードは同時に削除されますが、プライマリ・コントローラのレコードは依然として存在します.したがって,マスタ側の多対多削除のみが最も簡単で,直接的である.コードは次のとおりです.
/**
	 *          (         )
	 */
	public void testDelete() {
		String id = "402881ee175f04be01175f04c05d0001";
		Session session = HibernateSessionFactory.getSession();
		session.beginTransaction();
		Course c1 = (Course) session.get(Course.class, id);
		session.delete(c1);
		session.getTransaction().commit();
		session.close();
	}

もしあなたがこの时に直接被制御者を削除したいならば、とても残念なことにあなたに教えて、あなたは半分しかできなくて、あなたはただ简単に被制御者の记录を削除しただけで、関连関系は依然として中间表の中に存在して、システムはいつでもあなたの関连アクセスのために间违いを报告して、コードは以下の通りです:
	/**
	 *          (         )
	 */
	public void testDeleteByInverse() {
		String id = "402881ee175a2e7c01175a2e7ead0003";
		Session session = HibernateSessionFactory.getSession();
		session.beginTransaction();
		Teacher t1 = (Teacher) session.get(Teacher.class, id);
		session.delete(t1);
		session.getTransaction().commit();
		session.close();
	}

被制御者を削除したい場合、関連付けを削除したい場合は、次のコードを参照してください.
	/**
	 *          (         )
	 */
	public void testDeleteByInverse2() {
		String id = "402881ee175f04be01175f04c06c0002";
		Session session = HibernateSessionFactory.getSession();
		session.beginTransaction();

		Teacher t1 = (Teacher) session.get(Teacher.class, id);

		Set<Course> cs = t1.getCourses();
		for (Course c : cs) {
			c.getTeachers().remove(t1);
		}

		session.delete(t1);
		session.getTransaction().commit();
		session.close();
	}

完成しました.しかしSpring+Hiberanteの下で多対多削除であれば、エラーが報告される可能性があります.現在の解決策は両端のcascadeをnoneに設定することです.事務と関係がある可能性があると初歩的に断定した.
中間テーブルのみ削除:
/** 
*               (       ) 
*/ 
public void testDeleteByInverse3() { 
String id = "402881ee1782dad9011782dadb310001"; 
Session session = HibernateSessionFactory.getSession(); 
session.beginTransaction(); 

Course c1 = (Course) session.get(Course.class, id); 
c1.setTeachers(null); 

session.getTransaction().commit(); 
session.close(); 
} 


/** 
*               (       ) 
*/ 
public void testDeleteByInverse4() { 
String id = "402881ee1782dbd4011782dbd64a0002"; 
Session session = HibernateSessionFactory.getSession(); 
session.beginTransaction(); 

Teacher t1 = (Teacher) session.get(Teacher.class, id); 
Set<Course> cs = t1.getCourses(); 
for (Course c : cs) { 
c.getTeachers().remove(t1); 
} 

session.getTransaction().commit(); 
session.close(); 
}

この問題は、データベースの外部キーによるカスケード削除によっても解決できるはずである.