2017-06-13 3 views
6

エンティティが別のエンティティを使用でき、別のエンティティを使用する可能性があるので、同じエンティティを参照するManyToMany関係を定義しています。私はlistUseとlistUsedByを有することができ、両者は同じテーブルentity_usageに保持されている:@ManyToManyを同じテーブルの2つのリストで使用する方法

@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:エンティティエンティティBCを使用することができ、エンティティのでBCは、Aによって使用される。 私の問題は、listUseにBとCを追加するとentity_usageに保持されますが、listUsedByを表示しようとするとプロジェクトを再デプロイする必要があります。そうでなければlistUsedByは空のままです。プロジェクトを再デプロイする必要があります。

+0

したがって、双方向のManyToMany関連が必要です。ここにドキュメントがあります:https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#associations-many-to-many-bidirectional –

答えて

3

これは一般的なアプローチです:

@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); 
    } 
} 

、それが使われています:

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); 
} 

は、一般的に、これはトランザクションのEJBメソッドです。
エンティティは既にem.findで管理されているため、em.mergeは必要ありません。 はとにかく、あなたは(マージ、永続化、クエリ見つける。)あなたのエンティティを管理するために使用しますどちらの方法、それは両方のエンティティがを管理されている場合にのみ、addUsing/addUsedByを呼び出すことが重要です覚えています。

これは、ORMロジックが独自に処理できない主な取り組みの1つです。これらの関係の両方のエンティティ(親と子)に通知する必要があります。
リレーションシップを片側だけに設定するだけでは不十分です.AだけがBの親であると言うだけでは、Bは依然として誰がその親であるかまだ分かりません。

しかし、関係の所有側(parent.getChildren().add(child))のみを設定し、子をフラッシュし、更新するなどの代替アプローチがあります。

しかし、(私の肌で非常によく経験したように)実際の複雑なアプリケーションでは、選択肢は非常に扱いにくいです。

何らかの種類の挿入注文が必要な場合を除き、補足として、Listの代わりにSetを使用します。

+0

私がmappedByを追加したことを示唆しましたが、片方だけで動作します(use)。usedByにオブジェクトを追加すると、何もテーブルに保持されません。entity_usage –

+0

マッピングだけでなく、使い方です。答えの残りの部分は、その背後にある一般的な概念をカバーしています。あなたが**どのように*あなた*リンク* 2つのエンティティ(EJB/JPA /トランザクションコード)を投稿すれば、私はより正確になります。 –

+0

私はmanytomany関係の2つの側面があることを読んだ、所有者側(使用)とmappedby属性を持つ逆側(usedBy)があり、修正は所有者側からのみ可能である。別の質問を投稿してください –

関連する問題