1

我有几个表以每个子类的方式映射。

层次结构的顶部是 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。

4

1 回答 1

2

您试图让 EmployeeTransaction 的两个不同的持久实例具有相同的 ID。这是不可能的。您必须删除 EmployeeTransaction,(可能)刷新会话,然后使用相同的 ID 保存新的会话。

请注意,与原始 EmployeeTransaction 的所有关联也必须删除。如果这不可能,那么您不应该有继承关系,而是组合关系:一个 EmployeeTransaction 有(零或)一个 HiringTransaction。

于 2012-08-06T20:34:48.030 回答