12 Temmuz 2018 Perşembe

JPA @OneToMany Ilişki - Bidirectional

Giriş
1. Bidirectional ilişki join tablosu ile veya join tablosu olmadan kurulabilir.
2. Her iki kullanımda da 
- Bir tarafa @OneToMany
- Diğer tarafa @ManyToOne yazılır

Bu yazıda Owner kavramına kod açısından baktım çünkü bu şekilde anlaması daha kolay. Veritabanı açısından bakınca owner taraf kodun tam tersi.

Bu ilişki LAZY. Açıklaması şöyle.
OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER
1. Join Tablosu Olmadan

2. Join Tablosu Kullanarak

2.1 Join Tablosu Mevcutsa
Örnek
Şeklen şöyle


Şöyle yaparız
@Entity
@Table(name = "courses")
public class Course {
  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE)
  private Long id;

  @OneToMany(mappedBy = "course", cascade = CascadeType.ALL)
  private Set<CourseStudent> students = new LinkedHashSet<>();

  @Column(nullable = false)
  private String name;
  // getters and setters
}

@Entity
@Table(name = "students")
public class Student {
  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE)
  private Long id;

  @OneToMany(mappedBy = "student", cascade = CascadeType.ALL)
  private Set<CourseStudent> courses = new LinkedHashSet<>();

  @Column(nullable = false)
  private String name;
  // getters and setters
}

@Entity
@Table(name = "courses_students")
@IdClass(CourseStudentPk.class)
public class CourseStudent {
  @Id
  @ManyToOne
  @JoinColumn(name = "course_id")
  private Course course;

  @Id
  @ManyToOne
  @JoinColumn(name = "student_id")
  private Student student;

  @Column(nullable = false)
  private Instant registrationDate = Instant.now();

  private Short grade;
  // getters and setters
}

public class CourseStudentPk implements Serializable {
  private Long course;
  private Long student;
  // getters and setters
}

2.2 Join Tablosu Otomatik Oluşturulsun
Eğer join tablosu olsun istiyorsak parent tarafında OneToMany ve mappedBy + JoinColumn kodunu yazmak yeterli. Bu durumda join tablosu otomatik olarak oluşturulur. Yani A tablosu, B tablosu ve A_B join tablosu vardır.

Bu durumda @JoinColumn anotasyonu parent nesneye kodlanır. Child nesne silinmeden parent nesne silinebilir. Aradaki ilişkiyi koparmak için şuna benzer bir sql çalıştırılır
update child set parentID=null where parentID=?

Örnek
Parent tarafta şöyle yaparız
@OneToMany
@JoinColumn(name = "parentID")
private Set<Child> childs;
Child sınıfta şöyle yaparız
public class Child {

  @Id
  private long id;

  @ManyToOne
  private Parent parent;
}


Hiç yorum yok:

Yorum Gönder