我在JPA 2中的孤儿删除存在问题。在事务内部,我创建了一对一关系的目标对象(OrderDirectDebit),然后将其添加到现有的持久性DonationIntent(使用合并方法)。然后我通过使其无效来删除关系。然后我再次坚持(再次使用合并方法)。
我为关系配置了orphanRemoval,但仍未删除该对象。 规范说当调用刷新操作时应用remove操作(一旦事务结束就应该发生)。但在我的例子中,孤立的实体在提交后仍然存在。当我在合并操作(在我的自定义持久化方法中)手动调用flush后,孤立实体将被删除。如果我在使用相同持久化上下文(来自拦截器)的不同实体管理器上手动调用刷新操作,则孤立实体不会被删除。
我无法理解这种行为。合并后我是否必须直接手动调用?这有任何意义吗?请评论。以下是我的类定义,存储库的持久化方法和单元测试代码:
// this is a method of a stateless bean with transaction required
// it is run inside an arquillian unit test
public void testOrderCreation() {
DonationIntent donation = repositoryDonationIntent.findById(id);
Country country = testhelper.getCountryGermany();
BankAccount bankAccount =testhelper.getBankAccountForTestPerson1();
Assert.assertFalse(donation.createOrderDirectDebit(23.0d, country, OrderType.EState.NEW, bankAccount).hasErrors());
donation = repositoryDonationIntent.persist(donation);
Assert.assertNotNull(donation.getOrder());
donation.setOrder(null);
donation = repositoryDonationIntent.persist(donation);
Assert.assertTrue(repositoryDonationIntent.findById(donation.getId()) == donation);
Assert.assertNull(repositoryDonationIntent.findById(donation.getId()).getOrder());
//the assert verifies the the relation of the object in the persistence context is null,still after commit it does not remove it
}
实体模型:
@Entity
public class DonationIntent extends AutoIdDomainObject implements IAggregateRoot<Long> {
@OneToOne(cascade = CascadeType.ALL, optional = true, orphanRemoval = true)
private OrderType order; // this is the relation that does not get orphaned
}
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class OrderType extends AutoIdDomainObject {
// some more attributes and relations here
}
@Entity
public class OrderDirectDebit extends OrderType {
// some more attributes and relations here
}
存储库的持久化方法:
@Override
public <D extends IDomainObject<?>> D persist(Class<D> domainClass, D domainObject) {
//TODO Do not permit old revisions of versioned objects to be persisted
if (domainObject == null)
return null;
// invalid domain objects may not be persisted
if (!domainObject.isValid()) {
DomainObjectErrorLogger.log(domainObject.getErrors());
return domainObject;
}
// check if update or insert
if (isPersistent(domainClass, domainObject)) {
domainObject = em.merge(domainObject);
em.flush(); // a call to flush here will remove orphaned entity
} else {
em.persist(domainObject);
}
return domainObject;
}