2012-03-31 14 views
4

との永続化@OneToMany関係:コンストラクタに私は2つのエンティティ持っ@JoinColumnと@MapKeyColumn

@Entity 
Article { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL) 
    @JoinColumn(name="embed_id", referencedColumnName="id") 
    @MapKeyColumn(name = "language") 
    @MapKeyEnumerated(EnumType.ORDINAL) 
    private Map<Language, Locale> locales; 

    Article() { 
     locales.put(Language.CS, new Locale()); 
     locales.put(Language.EN, new Locale()); 
    } 
} 

@Entity 
Locale { 
    @Id 
    private Long embed_id; 

    @Id 
    private Language language; 

    @Column(length = 256) 
    private String name; 
} 

おかげで、私はArticleがインスタンス化されるとことを、確認することができ、2 Locales(CascadeType.ALL付き)それに関連付けられています。私は、このようなエンティティを永続化しようとすると、

問題が来る - 私が取得しています:

javax.persistence.EntityExistsException: 
a different object with the same identifier value was already associated 
     with the session: org...Locale#[email protected] 

を問題が持続し、休止状態は後にそれらを関連付けないときembed_id、またlanguageどちらも条から値が割り当てられていることです永続的な記事。これはどうすればできますか?

編集1:

私はembed_idlanguageが手動で設定されている場合、すべてが正常に動作することを確認しました。 @OneToManyの関係に従って、@JoinColumnと@MapKeyColumnの値を設定するだけで、Hibernateに伝える必要があります。

編集2:

MapKeyColumnの問題は簡単に解決があります。

public void addLocale(Language l, Locale locale) { 
     locale.setLanguage(l); 
     this.locales.put(l); 
} 

をしかし、私はまだArticle.idからLocale.embed_idを関連付けるために休止状態伝えることができません。

編集3:

私は、物品のIDが正しく生成されていることがわかりますが、それはロケールに置かれていません。

DEBUG org.hibernate.event.internal.AbstractSaveEventListener - 
    Generated identifier: 87, using strategy: org.hibernate.id.SequenceGenerator 
DEBUG org.hibernate.event.internal.AbstractSaveEventListener - 
    Generated identifier: component[language,embedId]{language=0, embedId=null}, using strategy: org.hibernate.id.CompositeNestedGeneratedValueGenerator 
DEBUG org.hibernate.event.internal.AbstractSaveEventListener - 
    Generated identifier: component[language,embedId]{language=1, embedId=null}, using strategy: org.hibernate.id.CompositeNestedGeneratedValueGenerator 

答えて

0

私はようやく答えを見つけました!トリックは記事にセッターを作成し、次のようにIDへのアクセスを追加しました:

@Id 
@Getter 
@Access(AccessType.PROPERTY) 
@GeneratedValue(strategy = GenerationType.AUTO) 
private Long id; 

public void setId(Long id) { 
    this.id = id; 
    this.getLocale(Language.CS).setEmbedId(id); 
    this.getLocale(Language.EN).setEmbedId(id); 
} 
3

私は問題があると思い、あなたのことを2つの空のロケールを永続化したいまた、IDフィールドにジェネレータを使用しないため、ロケールは同じ(空の)主キーを持ち、永続化できません。

+0

、私は知っているが、どのように私は地図のキーに関連付けるために休止状態に伝えることができますか?それは言語だけではありません。なぜなら、手動で設定すると、 'ヌル値の列 'embed_idがnullでない制約に違反しているからです。' –

+0

' embed_id'は必ずしも一意ではありません( '一意性を達成するため)。おそらく、一意でないキーは 'map'の(ユニークな)キーにはなりませんか? –

+0

言語との組み合わせでユニークです。主キーは 'embed_id、language'の組み合わせです。 –

関連する問題