我在單個事務中遇到多個EntityManager.merge()
調用的問題。這是使用Oracle數據庫。這兩個對象都不存在。實體:多個Eclipselink需要Flush()在同一個事務中合併?
public class A {
@Id
@Column("ID")
public Long getID();
@OneToOne(targetEntity = B.class)
@JoinColumn("ID")
public B getB();
}
public class B {
@Id
@Column("ID")
public Long getID();
}
合併代碼看起來是這樣的:
@Transactional
public void create(Object A, Object B) {
Object A = entitymanager.merge(A);
B.setId(A.getId());
entitymanager.merge(B);
}
對象是通過序列生成的ID,並大幹快上B.在日誌中尋找正確設置,合併對A被稱爲在合併之前調用B。從A到B有一個@OneToOne映射。但是,在實際提交時,在方法結束時,它會嘗試在B上執行INSERT,然後執行A上的INSERT操作,該操作會引發IntegrityConstraintViolation
,因爲「父鍵未找到」。
如果我在第二次合併之前添加entitymanager.flush()
,它工作正常。
@Transactional
public void create(Object A, Object B) {
Object A = entitymanager.merge(A);
entitymanager.flush();
B.setId(A.getId());
entitymanager.merge(B);
}
但是,flush()
是一個昂貴的操作,不應該是必需的。所有這些應該發生在同一個交易中(默認傳播@Transactional
是Propagation.REQUIRED
)。
任何想法爲什麼這不起作用,沒有flush()
,以及爲什麼即使合併A發生在B上的合併之前,實際上在COMMIT上的INSERT被顛倒了?
據我所知,A和B有一個「@ OneToOne」關係,下面的方法在對象A上: `@OneToOne(fetch = FetchType.EAGER,cascade = CascadeType.REMOVE,optional = true, targetEntity = B.類) public B getB(){}` – Trisfall 2011-12-19 13:25:57
通過「設置你的約束被推遲」,你是否引用數據庫中沒有外鍵約束?這似乎也不是一個好的選擇。我不得不認爲必須有一種方法來強制執行Eclipselink中的INSERT語句的順序。 – Trisfall 2011-12-19 13:58:33