2017-06-13 46 views
6

Bir varlığın başka bir varlık kullanabileceği bir durum var ve başka biri tarafından kullanılabilir, dolayısıyla aynı varlığı referans alan bir ManyToMany ilişkisi tanımladım i listUse ve listUsedBy sahip olabilir ve her ikisi de aynı tablo entity_usage kalıcıyken:@ManyToMany ile aynı tablodaki iki liste nasıl kullanılır?

@ManyToMany 
@JoinTable(name = "entity_usage", 
     joinColumns = { 
      @JoinColumn(name = "id_use", referencedColumnName = "id")}, 
     inverseJoinColumns = { 
      @JoinColumn(name = "id_used_by", referencedColumnName = "id")}) 
private List<Entity> listUse; 

@ManyToMany 
@JoinTable(name = "entity_usage", 
     joinColumns = { 
      @JoinColumn(name = "id_use_by", referencedColumnName = "id")}, 
     inverseJoinColumns = { 
      @JoinColumn(name = "id_use", referencedColumnName = "id")}) 
private List<Entity> listUsedBy; 

Exemple: Nesne bir Varlık B ve kullanabilir, idarenin böylece B ve C, A tarafından kullanılır. Şimdi benim sorunum, B ve C'yi listeye eklediğimde, bunlar entity_usage öğesinde kalıcıdır, ancak listeyi göstermeye çalıştığımda listUsedBy projeyi yeniden konuşlandırmam gerekir, aksi halde listUsedBy boş kalır, listesizimi yenilemenin bir yolu var. projemi yeniden konuşlandırmam gerekiyor.

+0

Yani, iki yönlü bir ManyToMany ilişkilendirmesi istiyorsunuz. İşte belgeler: https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#associations-many-to-many-bidirectional –

cevap

3

Bu genel yaklaşım:

@Entity 
public class SomeEntity 
{ 
    @ManyToMany 
    @JoinTable(name = "entity_usage", 
     joinColumns = @JoinColumn(name = "using_id"), 
     inverseJoinColumns = @JoinColumn(name = "used_by_id")) 
    private Set<SomeEntity> using = new LinkedHashSet<>(); 

    @ManyToMany(mappedBy = "using") 
    private Set<SomeEntity> usedBy = new LinkedHashSet<>(); 

    public void addUsing(SomeEntity entity) 
    { 
     this.using.add(entity); 
     entity.usedBy.add(this); 
    } 

    public void addUsedBy(SomeEntity entity) 
    { 
     this.usedBy.add(entity); 
     entity.using.add(this); 
    } 
} 

ve kullanılır:

public void someMethod(long parentEntityId, long childEntityId) 
{ 
    EntityManager em = getSomeEntityManager(); 

    SomeEntity parentEntity = em.find(SomeEntity.class, parentEntityId); 
    SomeEntity childEntity = em.find(SomeEntity.class, childEntityId); 

    parentEntity.addUsing(childEntity); 
} 

tipik olarak bu işlem EJB yöntemidir.
em.merge adlı öğeye gerek olmadığına dikkat edin; çünkü varlıklar zaten tarafından em.find tarafından yönetilmektedir. Neyse, (, birleştirme devam etmesi, sorgu bulabilirsiniz) varlıkları yönetmek için kullanacağız hangisi yöntem, yani her iki tarafın yönetilen yalnızca addUsing/addUsedByaramaya önemli hatırlıyorum.

Bu, ORM mantığının kendi başına işleyemediği ana tutarsızlıklardan biridir: Her iki öğeyi de (üst ve alt) ilişkisini bildirmeniz gerekir.
İlişkinin yalnızca bir tarafa ayarlanması yeterli değildir - sadece A'nın B'nin ebeveyni olduğunu düşünüyorsanız, B hala ebeveyninin kim olduğunu bilmez. Bununla birlikte, yalnızca ilişkinin (parent.getChildren().add(child)) sahipliğini belirleme, kızarma ve çocuğu yenileme gibi alternatif yaklaşımlar vardır. Yine de (cildim üzerinde çok iyi tecrübe ettiğim gibi) alternatiflerin gerçek dünyadaki karmaşık uygulamalarda ele alınması çok zordur.

Bir yan not olarak, bir tür ekleme siparişine ihtiyacınız olmadıkça, ilişki için List yerine Set kullanırdım.

+0

size bir mappedBy eklediğimi önerdi, ama yalnızca bir tarafta çalışır (using), bir nesneyi usedBy'ye eklediğimde, tablodaki hiçbir şey kalıcı değildir. –

+0

Sadece eşleme değil, kullanılan şekilde. Cevabın geri kalanı, arkasındaki genel kavramı kapsamaktadır. Eğer bir mesaj gönderiyorsanız ** iki nesneyi nasıl * * * * bağlarsınız - EJB/JPA/işlem kodu - Daha kesin olabilirim. –

+0

Pek çok şehir ilişkisinde iki tarafın olduğunu, sahip tarafının (kullanma) ve eşlemeli niteliğe sahip ters tarafının (usedBy) olduğunu ve değiştirmenin yalnızca sahip tarafından mümkün olduğunu, bunun için bir çözüm olup olmadığını okudum başka bir soru göndermek –