6

@ManyToOne関係を持つ他の2つのエンティティを含むエンティティがあります。

@Entity
public class A extends Serializable{

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @Cascade(CascadeType.SAVE_UPDATE)
    private B b;

    @ManyToOne
    @Cascade(CascadeType.SAVE_UPDATE)
    private C c;

}

別のAレコードの「B_ID」と「C_ID」を持つAインスタンスを保存しようとすると、例外が発生します。

org.hibernate.NonUniqueObjectException:同じ識別子値を持つ別のオブジェクトがすでにセッションに関連付けられていました

例えば:

A table
|   ID  |   B_ID    |   C_ID    |
|    1  |      1    |   null    |    // this works
|    2  |   null    |      1    |    // this works
|    3  |      1    |      x    |    // this throws the exception
|    4  |      x    |      1    |    // this throws the exception

x=any value of existent B/C_ID 

B_IDとC_IDは私のモデルでは一意ではなく、(B_ID + C_ID)は一意の制約ではありません!!

私に何ができる?

少し早いですがお礼を。

4

1 に答える 1

17

Hibernateは、ここではデータベースの一意性について不平を言っていません。現在Session、保存しようとしている新しいオブジェクトと同じIDのオブジェクトが現在のオブジェクトにすでに含まれていると不平を言っています。これは許可されません-Hibernateには、特定のIDを単一のセッションのスコープ内の2つの異なるオブジェクトで表すことができないという厳格な要件があります。

ある時点で、アプリケーションは同じIDを持つエンティティを保存してロードし、そのオブジェクトはすでにセッションに「登録」されています。この特定のケースでは、例外テキストが明確でないため、どのIDについて不平を言っているのかを判断するのは困難です。カスケードディレクティブを一時的に削除して、それでも発生するかどうかを確認し、絞り込んでみてください。

必要に応じて、セッションに特定のIDの既存のオブジェクトを「忘れる」ように強制することができます(Session.evict()HibernateAPIまたはJPA2.0 APIでEntityManager.detach()使用)が、これはあまり洗練されたソリューションではありません。

繰り返しになりますが、この例外はデータベースの制約とはまったく関係ありません。これは、Hibernateが内部のメモリ内状態の一貫性を保護することに関するものです。

于 2010-08-22T22:34:31.710 に答える