3 OneToMany ManyToMany MappedBy Cascade

5306 ワード

1双方向1-N関連
1-N関連の場合、Hibernateは双方向関連を使用することを推奨し、1の一方が関連関係を制御するのではなく、複数の一方が関連関係を制御することを推奨します.
a.一方はクラスを表す
@Entity
@Table(name="team_1")
public class Team
{
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="team_id")
	private int id;
	private String name;
	@OneToMany(mappedBy="team",targetEntity=Student.class,cascade=CascadeType.ALL)
	
	
	private Set<Student>students=new HashSet<Student>();
//  set  get  
}

b.多い方が学生を表す
@Entity
@Table(name="student_1")
public class Student
{
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="student_id")
	private int id;
	private String name;
	@ManyToOne(targetEntity=Team.class,fetch=FetchType.LAZY)
	@JoinColumn(name="team_id",nullable=false,referencedColumnName="team_id")
	private Team team;
//  set  get  
}

c.持続化コード
                        Team team=new Team();
			team.setName("20150225");
			session.persist(team);
			Student student=new Student();
			student.setName("zhangsan");
			student.setTeam(team);
			
			
			
			Student student2=new Student();
			student.setName("lisi");
			student2.setTeam(team);
			
			session.save(student);
			session.save(student2);
			
			tx.commit();

永続化コードでは、まず一方のチームオブジェクトを作成し、保存しました.
その後、複数の方を作成し、保存しました.これは客観的な事実に合っている.まずクラスがあってこそ、あるクラスに属する学生がいるということだ.そうしないと、異常が投げ出されます.このようなプログラムについては、次の点に注意してください.
  • は、チームオブジェクトを永続化することが望ましい.プログラムがstudentオブジェクトを永続化したい場合、HibernateはStudentの外部キー属性に値を割り当てることができるため、つまりstudentテーブルのようにレコードを挿入する場合、そのレコードの外部キーはすでに値を制定しており、これは彼が参照する主テーブルレコードがすでに存在していることを示している.
  • まずstudentとteamの関連関係(student 2.setTeam(team);)を設定し、その後studentを保存します.順序が逆の場合、update文が追加されます.
  • チームオブジェクトが関連関係を制御できないことを示す@MappedBy属性がチームオブジェクトによって設定されているため、チームオブジェクトによって関連関係を設定しないでください.だから、1.チームのデータをstudentに割り当てるには、studentのsetTeam()メソッドでチームデータをバインドします.2.データ挿入/更新セッションを行う.save()/session.update()の場合、最後に操作するのはstudentです.
  • team側でcascade属性をALLに設定、@manyToOne側でカスケード属性
  • を設定しない
    2 N-N双方向関連
    双方向N−N関係では,両端にSet集合属性を用い,両端に集合属性へのアクセスを増やす必要がある.双方向N-N関係はテーブルを接続する方式しか採用できない.
    双方向N−N関連付けは,@ManyToManyを用いてSet集合属性をそれぞれ修飾し,両端に@JoinTableを用いてマッピング接続テーブルを表示する必要がある.プログラムが一方の端で制御関連関係を放棄したい場合は、この端の@ManyToMany注記でmappedbyプロパティを指定できます.この端では@JoinTableマッピング接続テーブルは不要です.
    次の例では、カリキュラムと学生の関係を示します.1つのコースは複数の学生が選択でき、1つの学生が複数のコースを選択できます.
    @Entity
    @Table(name="course_2")
    public class Course
    {
    	@Id
    	@GeneratedValue(strategy=GenerationType.IDENTITY)
    	@Column(name="course_id")
    	private int id;
    	private String name;
    	@ManyToMany(targetEntity=Student.class)
    	@JoinTable
    	(name="student_course",
    	joinColumns=@JoinColumn(name="courseId",referencedColumnName="course_id"),
    	inverseJoinColumns=@JoinColumn(name="studentId",referencedColumnName="student_id")
    	)
    	
    	private Set<Student> courses=new HashSet<Student>();

    }
    @Entity
    @Table(name="student_2")
    public class Student
    { 
    	@Id
    	@GeneratedValue(strategy=GenerationType.IDENTITY)
    	@Column(name="student_id")
    	private int id;
    	private String name;
    	@ManyToMany(targetEntity=Course.class,cascade=CascadeType.ALL)
    	@JoinTable
    	(name="student_course",
    	joinColumns=@JoinColumn(name="studentId",referencedColumnName="student_id"),
    	inverseJoinColumns=@JoinColumn(name="courseId",referencedColumnName="course_id")
    	)
    	
    	private Set<Course> courses=new HashSet<Course>();

    }
    3 Cascade
    (1)関連付けられたエンティティの場合、Hibernateはデフォルトではカスケード操作を有効にしません.親が保存されている場合、関連付けられた子エンティティは保存されません.異なる永続化操作のカスケード動作を有効にするために、Hibernateは下位のカスケードスタイルのように設定されています.
  • CascadeType.ALL:Hibernateがすべての永続化操作を関連エンティティにカスケードすることを指定します.
  • CascadeType.MERGE:Hibernateがカスケード更新操作を関連エンティティにカスケードすることを指定します.
  • CascadeType.PERSIST:Hibernateがカスケード保存操作を関連エンティティにカスケードすることを指定します.
  • CascadeType.REFRESH:Hibernateがカスケード同期オペレーションを関連エンティティにカスケードすることを指定します.
  • CascadeType.REMOVE:Hibernateがカスケード削除永続化操作を関連エンティティにカスケードすることを指定します.

  • (2)Hibernateはまた、孤児オブジェクトの削除(@OneToMany,@OneToOneのorphanRemovalプロパティでカスケードポリシーを開始)という特殊なカスケードポリシーをサポートしています.
    <span style="font-size:18px;">@OneToMany(mappedBy="team",targetEntity=Student.class,cascade=CascadeType.ALL,orphanRemoval=true)</span>

    このポリシーは、現在のエンティティ1の一端のみに対応し、下位データテーブルがプライマリ・テーブルの場合に有効です.roaphanRemovalポリシーを有効にしたカスケード操作では、プログラムがプライマリ・テーブル・エンティティを介してスレーブ・エンティティとの関連付けを切断した場合-プライマリ・テーブル・エンティティに対応するレコードは削除されませんが、プライマリ・テーブル・エンティティへの参照が失われたため、これらのスレーブ・エンティティが「孤児」になり、hibernateは自動的にレコードを削除します.
    (3)カスケードの設定について,Hibernateは次のように提案する.
  • @ManyToOneではカスケードを指す意味はありません.カスケード・オペレーションは、通常、プライマリ・テーブル・レコードからプライマリ・テーブル・レコードに伝播すべきであり、通常、テーブル・レコードからプライマリ・テーブル・レコードに伝播すべきではないため、@OneToOneと@OneToManyの関係にあります.
  • スレーブレコードがマスターテーブルレコードに完全に限定する場合、cascade=Cascadeを指定することができる.ALLは、orphanRemoval=trueカスケード・ポリシーに合わせて、テーブル・エンティティのライフサイクルをプライマリ・テーブル・エンティティに完全に渡します.
  • トランザクションでプライマリ・テーブル・エンティティとスレーブ・テーブル・エンティティを同時に使用する場合、cascade={CascadeType.PERSIST,CascadeType.MERGE}カスケード・ポリシーを考慮できます.