JPA级联持久化与实体ElementCollection键

10

我有两个JPA实体,就像这样:

@Entity
class Foo {
    @Id
    private long id;
    // ...
}

@Entity
class Bar {
    @ElementCollection(targetClass = String.class, fetch = FetchType.LAZY)
    @MapKeyJoinColumn(name = "foo_id", referencedColumnName = "id")
    @MapKeyClass(Foo.class)
    @Column(name = "content")
    @CollectionTable(name = "bar_foo_content",
                     joinColumns = @JoinColumn(name = "bar_id", referencedColumnName = "id"))
    @ManyToMany(cascade = CascadeType.ALL)
    private Map<Foo, String> fooContent = Maps.newHashMap();
    // ...
}

你可以看到,fooContent 字段在 BarFoo 之间形成了多对多的关系,因此我认为使用 @ManyToMany 来指定字段的级联是合适的。但是,当试图将一个带有一些 Foo → String 值的映射的 Bar 持久化时,我会收到以下异常:

javax.persistence.RollbackException: java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: <<instance of Foo>>

显然,EclipseLink没有级联持久化我的Foo实例。我应该如何注释fooContent以使级联持久化工作?


你的 Foo 是什么样子?异常看起来像是 Foo 和另一个实体之间存在问题。 - Uooo
@Uooo,使用上述完整代码(即Foo内没有更多字段)仍然存在错误。 - dflemstr
我遇到了同样的问题。你找到解决方案了吗? - drame
1
@drame 不,我已经解决了这个问题。 - dflemstr
2个回答

10
你不需要在这里使用@ManyToMany注释。对于ElementCollection的操作总是级联的。

1
即使没有@ManyToMany,异常也会被抛出。 - dflemstr
至少在MySQL中,外键具有级联限制。 - KIC

7
同时指定@ElementCollection@ManyToMany是错误的。这两个注解表示了OR映射大于一基数关系的不同概念。 ElementCollection是一个严格的聚合或组合关系,其中集合中的元素严格由其父对象拥有,并且与元素的任何交互,如查询等,都必须通过父对象完成。父对象与集合中的元素的多重性始终为一对多。元素实例在给定时间只能与一个父对象相关联。 ManyToMany表示更或多或少独立的实体之间的关系,可以单独查询和操作,并且与声明使用@ManyToMany注释的属性的实例无关。 ManyToMany关系意味着相关实例可以通过其他已声明的关系与任何数量的其他实例相关联。
我期望任何符合标准的JPA实现都将显示错误或展示“未定义”行为,以处理像此类属性注释的情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接