Jpa Eclipselink在多对一关系中执行意外插入
我在两个对象之间有一个非常基本的关系:Jpa Eclipselink在多对一关系中执行意外插入,jpa,eclipselink,many-to-one,Jpa,Eclipselink,Many To One,我在两个对象之间有一个非常基本的关系: @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
@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中只有一组有限的状态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试图保持的状态已经存在…)。
这里没有级联,所以问题不在那里,Hibernate(在JPA2中)的行为是例外。在同一个项目中,我已经建立了一些更为复杂的关系,我真的很惊讶地看到这种关系在这里不起作用。
提前感谢您的帮助。statusOfADao.getStatusOfAById()做什么 它是否使用相同的持久性上下文(相同的事务和EntityManager) 您需要使用相同的EntityManager,因为您不应该混合来自不同持久性上下文的对象 SaverPersista到底做什么?merge()调用应该能够正确地解决所有问题,但是如果您确实把对象搞砸了,那么可能很难按照预期的方式合并所有问题
你只是合并了一个,还是合并了它的状态?还可以尝试将状态设置为状态的合并结果。假设:@Id@GeneratedValue(策略=GenerationType.IDENTITY)
<强>让我们考虑StasoFoAdoA.GETStaseOfabyID(456):/P> 1。返回仅设置了id的“代理”对象:
2。返回新交易中的实体: StatusOfA o=em.find(StatusOfA.class,456)//em.getReference(StatusOfA.class,456); em.getTransaction().commit(); 返回o 3。返回分离的实体: 4。返回反序列化的序列化实体: 5。返回附加实体:结论:
感谢您的回复所有DAO共享同一实体管理器。getStatusOfAById执行查询。getSingleResult()。对象“a”和“anotherStatusOfA”也是附着的实体。就我对持久性机制的理解而言,甚至不需要合并……EclipseLink确实支持对分离对象的引用,尽管通常不建议混合使用托管对象和分离对象。merge()应用于解析分离的对象。我认为JPA规范只允许在没有级联持久化的情况下引用分离的对象,否则需要抛出错误。通常,对分离对象的混合引用不是一个好主意,因为分离对象不会反映对象的当前托管状态。
return new StatusOfA(456);
EntityManager em = emf.createEntityManager();em.getTransaction().begin();
StatusOfA o = em.find(StatusOfA.class,456);//em.getReference(StatusOfA.class,456);
em.detached(o);
return o;
return ObjectCloner.deepCopy(em.find(StatusOfA.class,456));
return em.find(StatusOfA.class,456);