JPA ManyToMany双向插件

时间:2016-11-04 23:19:24

标签: java jpa eclipselink

我有问题,我找不到解决方案。我有双向多对多的anotation。我在DB(mariaDB)中有这些表:

  • item
  • 部分
  • item_section

项目部分:

@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "item_section",
        joinColumns = {
            @JoinColumn(name = "item", nullable = false, updatable = false)},
        inverseJoinColumns = {
            @JoinColumn(name = "section", nullable = false, updatable = false)})
private Set<Section> sections;

部分:

@ManyToMany(fetch = FetchType.EAGER, mappedBy = "sections")
private Set<Item> items;

问题:

我先创建一些Sections。比我想创建项目&#34;在&#34;这个部分。所以我创建了Item的实例并将一些现有的Sections添加到set中(我从DAO获得的Sections)。如果我持久化Item,则创建item和item_section表中的记录。但是如果我从DAO获得一些受影响的部分并通过项目迭代设置数据库更改不在此处,则Sections实例处于与insert之前相同的状态。

我错了什么?

PS:我使用的是eclipselink,但我觉得它不是很有趣

正如@Chris所说,我打电话的确坚持了,但方向的一面已经存在。没有定义级联,因此在持久化部分期间不会持久化或合并。因此,我的staless和JTA解决方案的最佳解决方案是使用merge而不是persist on item并将MERGE级联添加到sections集合...

感谢所有前来帮助的人,尤其感谢@Chris

2 个答案:

答案 0 :(得分:0)

您似乎缺少属性cascade = CascadeType.ALL。你应该尝试改变

@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "item_section",
        joinColumns = {
            @JoinColumn(name = "item", nullable = false, updatable = false)},
        inverseJoinColumns = {
            @JoinColumn(name = "section", nullable = false, updatable = false)})
private Set<Section> sections;

@ManyToMany(cascade=CascadeType.ALL,fetch = FetchType.LAZY)
@JoinTable(name = "item_section",
        joinColumns = {
            @JoinColumn(name = "item", nullable = false, updatable = false)},
        inverseJoinColumns = {
            @JoinColumn(name = "section", nullable = false, updatable = false)})
private Set<Section> sections;

然后它正常工作。

我通过教程Hibernate Many-To-Many Bidirectional Mapping Example

发现了这个错误

希望这个帮助

答案 1 :(得分:0)

问题可能是错误使用eclipselink的默认启用的共享缓存。尝试通过添加以下persistence.xml来禁用它:

<shared-cache-mode>NONE</shared-cache-mode>

当您持久化或合并时,Section提供程序将其刷新到数据库并将Section实例添加到共享缓存,以便在下次请求时从内存中检索它。当您持久Item时,您只更新关系的一方,但另一方不会更新,并且变得不同步。在JPA中,与Java一般,应用程序或对象模型负责维护关系。如果您的应用程序添加到关系的一侧,那么它必须添加到另一侧。在this article中阅读有关双向映射中缓存的更多信息。 我可以提供以下问题的解决方案:

  1. persistence.xml
  2. 中停用整个应用程序的缓存
  3. 在检索DAO之前手动刷新Section,然后再将其检索到用户
  4. 通过更新关系的两面正确使用缓存: