使用@JoinColumn和@MapKeyColumn保持@OneToMany关系 [英] Persisting @OneToMany relations with @JoinColumn and @MapKeyColumn

查看:149
本文介绍了使用@JoinColumn和@MapKeyColumn保持@OneToMany关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个实体:

@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)与之关联.

Thanks to the constructor, I can make sure, that once an Article is instantiated, two Locales (with CascadeType.ALL) are associated with it.

当我尝试保留这样的实体时,问题就来了-我得到了:

The problem comes when I try to persist such entity - I am getting:

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

问题是,在持久化时embed_idlanguage都没有从Article中分配值,而在持久化Article之后,Hibernate没有关联它们.该怎么办?

The problem is that neither embed_id, nor language have assigned values from the Article when persisting and Hibernate does not associate them after persisting Article. How can this be done?

我检查了当手动设置embed_idlanguage时,一切正常.我只需要告诉Hibernate,根据@ OneToMany关系设置@ JoinColumn和@ MapKeyColumn的值.

I checked that when the embed_id and language are set manually, everything works correctly. I just need to tell Hibernate, to set the value of @JoinColumn and @MapKeyColumn according to the @OneToMany relation.

MapKeyColumn的问题有一个简单的解决方案:

The problem with MapKeyColumn has an easy solution:

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

但是我仍然无法告诉休眠状态来关联Article.id中的Locale.embed_id.

But I am still unable to tell hibernate to associate the Locale.embed_id from Article.id.

修改3:

我可以看到文章ID已正确生成,但是没有将其放置在语言环境中:

I can see that the ID of article is properly generated, but then it is not put in the locale:

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

推荐答案

我终于找到答案了!诀窍是在Article上创建Setter并添加对ID的访问权限,如下所示:

I finally found the anwswer! The trick was to create Setter on Article and add Access to id as follows:

@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);
}

这篇关于使用@JoinColumn和@MapKeyColumn保持@OneToMany关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆