Eclipselink在多对一关系中执行意外插入



我在两个对象之间有一个非常基本的关系:

@Entity  
public class A {  
  @ManyToOne(optional = false)  
  @JoinColumn(name="B_ID", insertable=false, updatable=true)  
  private StatusOfA sa; 
  getter+setter  
}
@Entity  
public class StatusOfA {  
  @Id    
  private long id; 
  @Column  
  private String status;  
  getter+setter  
}

DB中只有一组有限的StatusOfA
我在交易中对A执行更新:

@TransactionalAttribute
public void updateStatusOfA(long id) {  
  A a = aDao.getAById(123);  
  if(a != null) {  
    a.getStatusOfA().getId();  //just to ensure that the object is loaded from DB
    StatusOfA anotherStatusOfA = statusOfADao.getStatusOfAById(456);  
    a.setStatusOfA(aontherStatusOfA);  
    aDao.saveOrPersistA(a);  
  }  
}

saveOrPersistA方法正在此处合并"a"。

我希望Eclipselink只对"a"执行更新以更新StatusOfA,但它正在对StatusOfA表执行新的插入。Oracle由于一个独特的约束冲突而抱怨(Eclipselink试图持久化的StatusOfA已经存在…)。这里没有级联,所以问题不存在,Hibernate(在JPA2中)的行为也不例外
在同一个项目中,我已经建立了一些更复杂的关系,看到这里的关系不起作用,我真的很惊讶
提前感谢您的帮助。

statusOfADao.getStatusOfAById()做什么?

它是否使用相同的持久性上下文(相同的事务和EntityManager)?

您需要使用相同的EntityManager,因为不应该混合来自不同持久性上下文的对象。

saveOrPersistA到底做什么?merge()调用应该能正确地解析所有内容,但如果您确实把对象搞砸了,那么可能很难按照预期合并所有内容。

你只是合并了A,还是合并了它的状态?也可以尝试将状态设置为状态的合并结果。

假设:@Id@GeneratedValue(策略=GenerationType.IDENTITY)


让我们考虑statusOfADao.getStatusOfAById(456)的以下实现:

1.返回只有id集的"代理"对象:

 return new StatusOfA(456);

2.在新交易中返回实体:

EntityManager em = emf.createEntityManager();em.getTransaction().begin();

StatusOfA o=em.find(StatusOfA.class,456)//em.getReference(StatusOfA.class,456);em.getTransaction()commit();return o;

3.返回分离的实体:

    StatusOfA o = em.find(StatusOfA.class,456);//em.getReference(StatusOfA.class,456);
em.detached(o);
return o;

4.返回反序列化的序列化实体:

return ObjectCloner.deepCopy(em.find(StatusOfA.class,456));

5.返回附加实体:

return em.find(StatusOfA.class,456);

结论:

  1. Eclipselink只按"预期"处理实现N5
  2. Hibernate按照"预期"处理所有五个实现
  3. 没有分析什么行为符合jpa规范

最新更新