16 Mayıs 2018 Çarşamba

JPA ManyToMany İlişki

ManyToMany
Şu satırı dahil ederiz.
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
ManyToMany unidirectional veya bidirectional olabilir.  ManyToMany'de 3 tablo kullanılır. Person ve Address tablolarını birleştirmek için bir ara tablo yani JoinTable kullanılır. JoinTable'da iki tane Foreign Key alanı vardır.

Veri Yapısı
ArrayList, Set kullanılabilir. Alanın ilklendirilmiş olması gerekir.
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name="USER_VEHICLE",
           joinColumns=@JoinColumn(name="USER_ID"),
           inverseJoinColumns=@JoinColumn(name="VEHICLE_ID"))
Collection<Vehicle> vehicle = new ArrayList<>();

Unidirectional many-to-many - Ara Tablo
Person -> Ara Tablo -> Address.

Sadece Person sınıfında ManyToMany anotasyonu belirtilir. Address sınıfında belirtilmez. Yine ara tablo kullanılır.

- Eğer Person'dan Address silinirse sadece ara tablo kaydı silinir. Address silinmez.
- Eğer Person silinirse hem Person hem de ara tablo kaydı silinir. Address silinmez.

Bidirectional many-to-many - Ara Tablo
- Eğer Person'dan Address silinirse sadece ara tablo kaydı silinir. Address silinmez.

Bidirectional many-to-many with link entity - Ara Tablo
Yine ara tablo kullanır ancak A ve B direkt bağlanmak yerine  PersonAddress gibi bir ara sınıf kullanır.

cascade Alanı
Örnek
Owning side şöyle olsun.
@Entity
@Table(name = "product_details")
public class ProductDetails {

  private int productId;
  private String productName;

  @ManyToMany(cascade = { CascadeType.ALL })
  @JoinTable(
    name = "order_product", 
    joinColumns = { @JoinColumn(name = "productId") }, 
    inverseJoinColumns = { @JoinColumn(name = "orderId") }
  )
  private Collection<OrderDetails> orders = new ArrayList();
  ...
}
Diğer taraf şöyle olsun.
@Entity
@Table(name = "order_details")
public class OrderDetails {

  private int orderId;
  private String orderName;
  @ManyToMany(mappedBy = "orders")
  private Collection<ProductDetails> products = new ArrayList();
  ...
}
Örnek
Şöyle yaparız.
@ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE})
@JoinTable(
        name = "profile_skills",
        joinColumns = @JoinColumn(name = "profile_id", referencedColumnName = "id"),
        inverseJoinColumns = @JoinColumn(name = "skill_id", referencedColumnName = "id")
)
private Set<Skill> skills;
targetEntity Alanı
Örnek
A sınıfı şöyle olsun
@Entity
public class A {

  @Column(name = "a_id")
  String id;
  
  @ManyToMany(targetEntity = B.class,
              cascade = { CascadeType.PERSIST, CascadeType.MERGE })
  @JoinTable(name = "at",
             joinColumns = @JoinColumn(name = "a_id"),
             inverseJoinColumns = @JoinColumn(name = "b_id"))
  Set<Report> bSet;
}
joinColumn A tablosundaki id alanıdır.
inverseJoinColumn ise B tablosundaki id alanıdır.

B sınıfı şöyle olsun. Ya da şöyle olsun
@Entity
public class B {
  @Column(name = "b_id")
  String id;

  @ManyToMany(mappedBy = "bSet")
  Set<A> aSet;

}
Set yerine list kullanılabilir.

Hiç yorum yok:

Yorum Gönder