我的领域模型:支付和账户之间的单向多对一映射。
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "ACCOUNT_TYPE")
public abstract class Account { … }
@Entity
@DiscriminatorValue(Account.Constants.BANK_ACCOUNT)
public class BankAccount extends Account { … }
@Entity
public class Payment {
@ManyToOne
private Account receiver;
...
}
我的测试用例(扩展 AbstractJUnit4SpringContextTests):
@Test(expected=DataIntegrityViolationException.class)
public void deleteAccountReferencedByPayment() {
createPayment();
getTransactionTemplate().execute(new TransactionCallback<Object>() {
@Override
public Object doInTransaction(TransactionStatus status) {
Account receiver = accountRepository.findAllByEmail(email1).get(0);
accountRepository.remove(receiver);
return null;
}
});
}
这会导致 DataIntegrityViolationException,因为在启动事务提交后执行的 SQL 是:
- 从 ID=? 的 BankAccount 中删除
- 从 ID=? 的帐户中删除 和版本=?
现在我有一个奇怪的“特征”,当我
- 更改域以在 ManyToOne 映射上添加级联(尤其是 ALL 或 PERSIST)
- 并更改测试以在删除帐户时读取同一交易中创建的付款
进一步来说:
@Entity
public class Payment {
@ManyToOne(cascade = {CascadeType.PERSIST})
private Account receiver;
...
}
@Test(expected=DataIntegrityViolationException.class)
public void deleteAccountReferencedByPaymentStrangeBehaviour() {
final Long paymentId = createPayment();
getTransactionTemplate().execute(new TransactionCallback<Object>() {
@Override
public Object doInTransaction(TransactionStatus status) {
paymentRepository.find(paymentId);
Account receiver = accountRepository.findAllByEmail(email1).get(0);
accountRepository.remove(receiver);
return null;
}
});
}
这不会导致 DataIntegrityViolationException,因为在启动事务提交后没有执行任何 SQL。
任何想法是什么导致了这种行为?PERSIST 与查找付款或删除帐户有什么关系?这可能是 JPA 标准实施中的错误吗?顺便说一句,我将 JPA2 与 Hibernate 4.1.3.Final 一起使用。