我有几个以每个子类的方式映射的表。
层次结构的顶部是EmployeeTransaction,它包含一个复合主键类:
public class EmployeeTransaction implements Serializable {
private TransactionCompositeId id;
@Id
public TransactionCompositeId getId() { // etc }}
}
public static class TransactionCompositeId implements Serializable {
public String employeeId;
public Long transactionId;
// getters/setters
}
所以,我有一个子类是HiringTransaction:
@PrimaryKeyJoinColumns(//etc)
public class HiringTransaction extends EmployeeTransaction implements Serializable {
// etc
}
现在,有些情况需要自己创建一个EmployeeTransaction,然后直到稍后才与其中一个子类关联。
以下是单元测试中的一些代码,它导致NonUniqueObjectException:
@Test
@Rollback(false)
public void testSave()
{
final TransactionCompositeId id = new TransactionCompositeId("777777777",553942L);
EmployeeTransaction pt = new EmployeeTransaction(); pt.setId(id);
pt.setLastUpdate(date);
pt.setLastUpdatedBy(user);
pt.setCreatedBy(user);
pt.setCreationDate(date);
// various setters
employeeTransactionDAO.save(pt);
//EmployeeTransaction pt1 = employeeTransactionDAO.get(id);
TransactionCompositeId newId = new TransactionCompositeId("777777777",553942L);
HiringTransaction eth = new HiringTransaction();
BeanUtils.copyProperties(pt, eth);
//HiringTransaction eth = (HiringTransaction) pt;
//HiringTransaction eth = new HiringTransaction(pt);
eth.setId(newId);
// various setters/getters
dao.save(eth);
HiringTransaction tempEth = dao.get(id);
assertNotNull("HiringTransaction should not be null", tempEth);
dao.remove(id);
ptDAO.remove(id);
tempEth = dao.get(id);
EmployeeTransaction tempPt = ptDAO.get(id);
assertNotNull("EmployeeTransaction should not be null", tempEth);
assertNotNull("HiringTransaction should not be null", tempPt);
}
我怀疑我不能将这两个活动都放在一个UnitOfWork中。但是,我不知道如何解决NonUniqueObjectException。 id绝对是相同的,因为映射是每个子类的表。
注意:DAO是调用session.save(),session.merge()等的简单通用DAO。
答案 0 :(得分:2)
您正尝试使用相同的ID拥有两个不同的EmployeeTransaction持久化实例。这是不可能的。你必须删除EmployeeTransaction,(可能)刷新会话,然后保存具有相同ID的新会话。
请注意,还必须删除与原始EmployeeTransaction的所有关联。如果那是不可能的,那么你不应该有一个关注关系,而是一个组合关系:一个EmployeeTransaction有一个(零或)一个HiringTransaction。