2016-11-04 6 views
0

私は問題があり、解決策を見つけることができませんでした。私は双方向の多対多のアノテーションを持っています。JPA ManyToMany双方向インサート

  • 項目
  • item_section

アイテム部:

@ManyToMany(fetch = FetchType.LAZY) 
@JoinTable(name = "item_section", 
     joinColumns = { 
      @JoinColumn(name = "item", nullable = false, updatable = false)}, 
     inverseJoinColumns = { 
      @JoinColumn(name = "section", nullable = false, updatable = false)}) 
private Set<Section> sections; 

区間部分:

IはDB(mariaDB)にこのテーブルを持っています
@ManyToMany(fetch = FetchType.EAGER, mappedBy = "sections") 
private Set<Item> items; 

問題:

私は最初のいくつかのセクションを作成します。私はこのセクション内のアイテムを作成したいと思うよりも。だから私はItemのインスタンスを作成し、いくつかの既存のSectionsをセットに追加します(セクションはDAOから取得します)。 Itemを永続化すると、itemおよびsection_sectionテーブルのレコードが作成されます。しかし、私がDAOから影響を受けるセクションの一部を取得し、アイテムの繰り返しを設定した場合、データベースの変更はここにはありません。セクションのインスタンスは挿入前と同じ状態です。

何が間違っていましたか?

PS:私はEclipseLinkはを使用しますが、私は@クリスは私がutimately持続が、方向の片側がすでに存在していると呼ば言ったように、それは

SOLUTION

面白いではないと思います。カスケードは定義されていないため、永続セクションは永続化されず、マージされませんでした。だから私のstalessための最善の解決策は、およびJTAソリューションを使用したマージの代わりの項目を持続し、セクションのコレクションにMERGEカスケードを追加...助けに来た

おかげで誰もが、特に@クリス

+1

リレーションの両側を設定しても構いませんか?あなたが永続性コードを提示しないので、それ以上のコメントは不可能です。 –

+0

ありがとう@NeilStocktonしかし、あなたが望む持続コードは何ですか?私は単にentityManager.persist(item)を実行します。ここで、entityManagerはEntityManagerのインスタンスであり、itemはItemのインスタンスです。あなたは何を意味しているのですか?_ \t リレーションの両側を設定するのは気になりましたか?_私は両方とも設定していませんでしたか? – Majlanky

+0

永続性コードを掲示しない(あなただけがクラスを投稿した)ので、リレーションの両側を(永続化するオブジェクト内に)設定するかどうかは誰も言いません。だから、あなたは "item"を持続して呼び出す...あなたは他のオブジェクト(セクション)でpersistを呼び出しましたか?あなたがするまで誰もコメントすることはできません –

答えて

0

にあなたがしているようです属性cascade = CascadeType.ALLがありません。あなたはそれが正常に動作

@ManyToMany(cascade=CascadeType.ALL,fetch = FetchType.LAZY) 
@JoinTable(name = "item_section", 
     joinColumns = { 
      @JoinColumn(name = "item", nullable = false, updatable = false)}, 
     inverseJoinColumns = { 
      @JoinColumn(name = "section", nullable = false, updatable = false)}) 
private Set<Section> sections; 

@ManyToMany(fetch = FetchType.LAZY) 
@JoinTable(name = "item_section", 
     joinColumns = { 
      @JoinColumn(name = "item", nullable = false, updatable = false)}, 
     inverseJoinColumns = { 
      @JoinColumn(name = "section", nullable = false, updatable = false)}) 
private Set<Section> sections; 

を変更しようとする必要があります。

私はチュートリアルHibernate Many-To-Many Bidirectional Mapping Example

希望を経由してこの間違いを発見し、このヘルプ

+0

私はこれを行うことはできません。このカスケードを追加すると、永続化操作はすべての影響を受けるセクションにも呼び出されます。だから私は今DBの二重性を持っています。それは私がすべてのカスケードを削除した理由です。私はカスケードをしたくない。アイテムテーブルに挿入した後、影響を受けるセクションを更新したい。または、ある時点で間違っていますか? – Majlanky

+0

あなたは影響を受けたセクションが、アイテムへの参照が挿入されなかった後に更新されたことを意味します。実際に影響を受けたセクションにはまだ参照があります。ただし、FetchType.EAGERを使用しているため、項目を保持するときに同じセッションで影響を受けるセクションを取得し、参照がない場合があります。この問題が解決された他のセッションでそれらを取得する必要があります。または、EAGERをLAZYに置き換えて、すべて正常に動作します。 –

+1

もう一つ、ManyToManyの関係について私は、EAGERの代わりにLAZYを使用することを強くお勧めします。 –

0

問題は、デフォルトで有効になっているのEclipseLinkの共有キャッシュを使用して正しくないとすることができます。

<shared-cache-mode>NONE</shared-cache-mode>

をあなたが持続またはデータベースへSectionプロバイダのフラッシュにそれをマージし、それが次の要求にメモリから検索することができますので、共有キャッシュへSectionインスタンスを追加すると、次のpersistence.xmlに追加することによって、それを無効にしてください。Itemを維持すると、リレーションシップの一方の側のみが更新されますが、もう一方の側は更新されず、同期しなくなります。 JPAでは、一般にJavaのように、関係を維持するのはアプリケーションまたはオブジェクトモデルの責任です。アプリケーションがリレーションシップの一方の側に追加する場合は、他方の側に追加する必要があります。双方向マッピングによるキャッシングの詳細については、this articleを参照してください。 私はあなたの問題の次のソリューションを提供することができます:手動でリレーションシップの両側を更新することにより、正しく

  • ユーザーに使用したキャッシュを、それを取得する前にDAOでSectionをリフレッシュpersistence.xml
  • でアプリケーション全体のため

    1. 無効にキャッシュを:
  • 関連する問題