2016-04-06 7 views
1

現在、プロジェクトでHibernateを使用していて、多対多の関係を設定する際に問題があります。私は自分の問題がカスケード型に関係していると思う。多対多カスケード型の問題を解決する

シナリオには広告があり、各広告には多くのタグを付けることができますが、各タグは多くの広告に関連付けることができます。広告エンティティの多対多の注釈は次のとおりです。

@ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH }) 
@JoinTable(name = "adMediaAdvertiserTag", 
     joinColumns = { @JoinColumn(name = "adMediaId") }, 
     inverseJoinColumns = { @JoinColumn(name = "advertiserTagId") }) 

とタグエンティティの多対多マッピングは次のとおりです。

@ManyToMany(mappedBy = "advertiserTags", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE }) 

私はカスケード型の構成にしている場合応じて、2つの異なるエラーを見ていますタグはすでにデータベースに存在します。

広告のカスケード型が持続含まれていないとタグがすでに私たちは、この例外を取得存在しない場合:

TransientObjectException: object references an unsaved transient instance 

そして、広告上のカスケード型が含まれない場合が存続し、タグはすでに我々が得る存在しない:

PersistentObjectException: detached entity passed to persist 

私はこの作業を取得することができます唯一の方法は、各タグを通じてカスケードタイプではなく、ループとして存続し、セッションに保存していません。

これは正しい方法ですか?休止状態で自動的にこれを処理できる方法はありますか?

これがはっきりしていないか、それ以上の情報が必要な場合は教えてください。

UPDATE

私は保存方法にspringframeworkのCrudRepositoryオブジェクトを使用するサービスを使用してオブジェクトを保存しています。私は本当にすべてを投稿することはできませんので、コードがたくさんあります。

私は現在、保存しようとしているオブジェクトにマージまたは永続メソッドを呼び出していません。私はHibernateが私のためにそのようなことを処理するという印象の下にいました。

+0

タグのいくつかはすでに存在する可能性があり、そのうちのいくつかは新しいものであり、永続化する必要があるということです。もしそうなら、 'persist'メソッドの代わりに' merge'を呼び出すべきではないでしょうか? –

+0

はい、そうです。私はそれを試みましたが、新しいタグが追加されたときにTransientObjectExceptionが返されます:オブジェクトは保存されていない一時インスタンスを参照します –

+0

オブジェクトを保存するために使用されたCascadeTypeまたはメソッドを意味しますか? –

答えて

1

広告オブジェクトとタグオブジェクトを永続化するために使用しているコードを追加してください。私は(私はあなたに似て信じて)次のコードでテストされ、それが動作します:ユーザーで

User user = new User(); 
Role role = new Role(); 
role.setId("TEST_ROLE"); 
user.getRoles().add(role); 

entityManager.persist(user); 

User user2 = new User(); 
user2.getRoles().add(role); 
entityManager.persist(user2); 
System.out.println(user2.getId()); 

は私が持っている:

@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST) 
@JoinTable(name = "user_roles", 
     joinColumns = {@JoinColumn(name = "user_id", nullable = false, updatable = true)}, 
     inverseJoinColumns = {@JoinColumn(name = "role_id", nullable = false, updatable = true)}) 
protected List<Role> roles = new ArrayList<>(); 

と役割で

は、私が持っている:だから

@ManyToMany(mappedBy="roles") 
protected List<User> users; 
+0

答えがありがとうございますが、これは私が説明していたシナリオの1つで、既存のタグ(またはあなたの場合はロール)があるシナリオでは機能しませんでした。私はいくつかの文脈で質問を更新します。 –

+0

私は、persistメソッドへの呼び出しに気付きました。これは新しく作成されたオブジェクトごとに必要ですか? –

+0

はい、この場合、新しいユーザーを永続化する必要があり、カスケードのために間接的にRoleオブジェクトが永続化されます。 – Mustafa

関連する問題