2016-11-04 84 views
0

我有问题,我找不到解决方案。我有双向多对多的诠释。我在DB(MariaDB的)这个表:JPA ManyToMany双向插入

  • 项目
  • 部分
  • 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; 

问题:

我先创建一些章节。比我想在本节创建项目“内”。所以我创建Item的实例并添加一些现有的节到集(我从DAO得到的部分)。如果我坚持该项目,创建项目和item_section表格中的记录。但是,如果我从DAO中得到一些受影响的部分并遍历项目集数据库更改不在此处,则部分实例与插入之前处于相同状态。

我错了什么?

PS:我使用的EclipseLink,但我不认为这是有趣的

SOLUTION

正如@克里斯说,我叫utimately坚持,但方向的一侧已经存在。没有定义级联,所以在坚持部分没有坚持也没有合并。所以我staless和JTA的解决方案最好的解决办法是使用合并,而不是坚持下去的项目,并添加合并级联部分集合...谁前来帮忙,但尤其是@克里斯

+1

你打算设置关系的两边吗?由于您没有提供持久性代码,因此不可能有进一步的评论。 –

+0

谢谢@NeilStockton,但你想要什么持久性代码?我只需做entityManager.persist(item),其中entityManager是EntityManager的实例,item是Item的实例。你是什​​么意思“_ \t 你是否打算设置关系的两边?_”我已经设定他们都不是我? – Majlanky

+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

希望这有助于

+0

我不能这样做。如果我添加这个级联比坚持操作也被调用到所有受影响的部分。所以我现在在数据库中有口实。这是我删除所有cascased的原因。我不想做任何级联。插入项目表后,我想要更新受影响的部分。或者我在某些时候错了? – Majlanky

+0

您的意思是插入后没有引用项目,更新了受影响的部分,对不对?实际上受影响的部分仍然有对它们的引用。但是,您正在使用FetchType.EAGER,因此当您对项目进行persit时没有任何引用,您将获得受影响的部分。您应该在其他会话中解决此问题。或者您可以将EAGER替换为LAZY,然后一切正常。 –

+1

还有一件事,对于ManyToMany的关系,我强烈建议您使用LAZY而不是EAGER –

0

问题可能是不正确的使用的EclipseLink的这是默认启用的共享缓存的发现了这个错误。尝试通过添加persistence.xml将其禁用以下内容:

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

当你坚持下去或合并Section提供商刷新它的数据库,并添加Section实例共享缓存,因此它可以从内存上的下一个请求被检索。当你坚持Item你只更新关系的一方,但另一方不会更新,并且不同步。在JPA中,就像在Java中一样,维护关系是应用程序或对象模型的责任。如果您的应用程序添加到关系的一侧,那么它必须添加到另一侧。在this article中详细了解双向映射中的高速缓存。 我可以提供以下你的问题的解决方案:在persistence.xml

    1. 为整个应用程序禁用缓存它通过更新关系的双方
    2. 使用缓存正确地检索到用户之前手动刷新Section在DAO: