5

我有一个与 customerBudget 实体有关联的客户。CustomerEntityListener 将创建一个 customerBudget 实体。

我收到以下错误:

IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: de.company.entity.Customer-c4775b5b-413b-0567-3612-e0860bca9300 [new,managed].

onAfterInsert(客户实体)中的代码

    LoadContext<Customer> loadContext = LoadContext.create(Customer.class);
    loadContext.setId(entity.getId());
    Customer customer = dataManager.load(loadContext);

    CustomerBudget customerBudget = new CustomerBudget();
    customerBudget.setCustomer(customer);

    CommitContext commitContext = new CommitContext(customerBudget);
    dataManager.commit(commitContext);

如何在 EntityListener 中创建和持久化实体?

4

1 回答 1

5

您可以通过 实现BeforeInsertEntityListener接口并在当前持久化上下文中创建一个新实体EntityManager

侦听器可能如下所示:

@Component("demo_CustomerEntityListener")
public class CustomerEntityListener implements BeforeInsertEntityListener<Customer> {

  @Inject
  private Metadata metadata;

  @Inject
  private Persistence persistence;

  @Override
  public void onBeforeInsert(Customer entity) {
    CustomerBudget customerBudget = metadata.create(CustomerBudget.class);
    customerBudget.setCustomer(entity);
    persistence.getEntityManager().persist(customerBudget);
  }
}

新实体将与客户一起在事务提交时保存到数据库中。

Metadata.create()方法是实例化实体的首选方法——对于具有整数标识符的实体,它从序列中分配一个 ID;如果需要,它还可以处理实体扩展。

实体侦听器在保存实体的事务中工作,这允许您对数据进行原子更改 - 所有内容都将与调用侦听器的实体一起保存或丢弃。

与 不同EntityManagerDataManager总是创建一个新事务。因此,仅当您确实想在单独的事务中加载或保存实体时,才应在实体侦听器中使用它。我不知道为什么你会得到这个特殊的异常,但你的代码看起来很奇怪:你加载了数据库中的 Customer 实例,而不是使用传递给侦听器的实例。当我尝试在 HSQLDB 上运行您的代码时,服务器进入无限锁定状态 - 内部的新事务DataManager等待直到当前保存客户的事务被提交。

于 2016-04-26T14:54:24.687 回答