我有一个客户,它与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].
Run Code Online (Sandbox Code Playgroud)
onAfterInsert(Customer实体)中的代码
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);
Run Code Online (Sandbox Code Playgroud)
如何在EntityListener中创建和持久化Entites?
小智 8
您可以通过实现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);
}
}
Run Code Online (Sandbox Code Playgroud)
新实体将与客户一起保存到事务提交中的数据库中.
该Metadata.create()
方法是实例化实体的首选方法 - 对于具有整数标识符的实体,它从序列中分配ID; 如果需要,它还处理实体扩展.
实体侦听器在保存实体的事务中工作,这允许您对数据进行原子更改 - 所有内容都将与调用侦听器的实体一起保存或丢弃.
与之不同EntityManager
,DataManager
总是创建一个新的交易.因此,只有在您真的想要在单独的事务中加载或保存实体时,才应在实体侦听器中使用它.我不确定为什么会遇到这个特殊的异常,但是你的代码看起来很奇怪:你加载了一个Customer实例,而不是使用传递给监听器的实例.当我尝试在HSQLDB上运行代码时,服务器进入无限锁定 - 内部的新事务DataManager
等待,直到保存Customer的当前事务被提交.