0

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

@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 表执行新插入。然后甲骨文抱怨独特的约束冲突(Eclipselink 试图坚持的 StatusOfA 已经存在......)。这里没有级联,所以问题不存在,Hibernate(在 JPA2 中)表现得异常。
在同一个项目中,我已经建立了一些更复杂的关系,我很惊讶地看到这里的关系不起作用。
在此先感谢您的帮助。

4

2 回答 2

0

statusOfADao.getStatusOfAById() 有什么作用?

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

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

saveOrPersistA 究竟做了什么?merge() 调用应该正确地解决所有问题,但是如果您确实弄乱了对象,则可能很难按预期合并所有内容。

您是仅合并 A,还是合并其状态?尝试将状态设置为状态的合并结果。

于 2011-06-06T15:00:41.023 回答
0

假设: @Id@GeneratedValue(strategy = 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(); 返回 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 规范的行为
于 2011-06-10T14:34:15.897 回答