簡體   English   中英

與@JoinColumn和@MapKeyColumn保持@OneToMany關系

[英]Persisting @OneToMany relations with @JoinColumn and @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就會將兩個Locales (與CascadeType.ALL)相關聯。

當我試圖堅持這樣的實體時,問題出現了 - 我得到了:

javax.persistence.EntityExistsException: 
a different object with the same identifier value was already associated 
      with the session: org...Locale#org...Locale@2bfdsc64

問題是embed_idlanguage都沒有在持久化時從文章中賦值,而Hibernate在持久化文章后沒有關聯它們。 如何才能做到這一點?

編輯1:

我檢查過,當手動設置embed_idlanguage ,一切正常。 我只需要告訴Hibernate,根據@ OneToMany關系設置@ JoinColumnMapKeyColumn的值。

編輯2:

MapKeyColumn的問題有一個簡單的解決方案:

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

但我仍然無法告訴hibernate將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

我想問題是,你想要堅持兩個空的語言環境。 並且因為您沒有為id字段使用生成器,所以語言環境具有相同的(空)主鍵,因此無法持久化。

我終於找到了anwswer! 訣竅是在文章上創建Setter並添加對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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM