gpt4 book ai didi

java - JPA 分离实体传递到持久化

转载 作者:太空宇宙 更新时间:2023-11-04 07:33:17 24 4
gpt4 key购买 nike

我有一个带有 @Transactional 注释和内部 EntityManager 的 DAO。

我还有一个 IOC 托管 bean,其中有一个事务方法。

并且有 2 个具有单向 Many2one 的实体 -

@Entity
@Table(name = "AU_EVENT")
public class AuEvent {
@ManyToOne(fetch= FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "MODULE_ID")
private AuModule auModule;
}

AuModule 没有对 AuEvents 的引用

我正在尝试这样做

@Async
@Transactional(propagation = Propagation.REQUIRED)
public void onEvent(String moduleName, String instanceName){
AuModule auModule = auModuleDao.findModule(moduleName, instanceName);
if (auModule == null) {
auModule = new AuModule();
auModule.setInstance(instanceName);
auModule.setName(moduleName);
}
//doesnt help
//auModule = auModuleDao.getEntityManager().merge(auModule);

AuEvent auEvent = new AuEvent();
auEvent.setAuModule(auModule);
auEventDao.persist(auEvent); // error here [AuModule detached]
}

正如我在https://stackoverflow.com/questions/14057333/detached-entity-passed-to-persist-error-with-onetomany-relation中读到的那样我尝试这样做

@Async
@Transactional(propagation = Propagation.REQUIRED)
public void onEvent(String moduleName, String instanceName){

AuEvent auEvent = new AuEvent();
auEventDao.persist(auEvent);

AuModule auModule = auModuleDao.findModule(moduleName, instanceName);
if (auModule == null) {
auModule = new AuModule();
auModule.setInstance(instanceName);
auModule.setName(moduleName);
}
auEvent.setAuModule(auModule);
auEventDao.persist(auEvent); // error here [AuEvent detached]
}

那么,有谁知道我该如何避免这种情况?PS 请不要建议我写这样的 DAO 方法 -

public void saveEvent(AuEvent auEvent, String moduleName, String instanceName){
log.info("saveEvent({}) called...", auEvent);
AuModule auModule = auModuleDao.findModule(moduleName, instanceName);
if (auModule == null) {
auModule = new AuModule();
auModule.setInstance(instanceName);
auModule.setName(moduleName);
}
auEvent.setAuModule(auModule);
persist(auEvent);
}

我确实想保存不在任何 DAO 内部的事件和模块

谢谢

最佳答案

在第二个示例中,您最终不应调用 auEventDao.persist(auEvent);auEvent附加,因此您的交易只需结束即可。
另外,您不应该对已经持久化的对象调用persist()。您应该仅在新对象上调用它。这也是你的第一个例子中的问题。

您仅在 auEvent 上调用 persist() 一次,这是正确的。但有时存在与此 auEvent 关联的现有(已持久存在,在数据库中找到)auModule。并且您使用 CascadeType.PERSIST 标记了此关联。因此,persist() 也级联到现有的 auModule -> 抛出异常

这样的事情应该有效:
1.

@Async
@Transactional(propagation = Propagation.REQUIRED)
public void onEvent(String moduleName, String instanceName){
AuModule auModule = auModuleDao.findModule(moduleName, instanceName);
if (auModule == null) {
auModule = new AuModule();
auModule.setInstance(instanceName);
auModule.setName(moduleName);
}
AuEvent auEvent = new AuEvent();
auEventDao.persist(auEvent);

auEvent.setAuModule(auModule);
auEventDao.merge(auEvent);
}


2.

@Async
@Transactional(propagation = Propagation.REQUIRED)
public void onEvent(String moduleName, String instanceName){

AuEvent auEvent = new AuEvent();
auEventDao.persist(auEvent);

AuModule auModule = auModuleDao.findModule(moduleName, instanceName);
if (auModule == null) {
auModule = new AuModule();
auModule.setInstance(instanceName);
auModule.setName(moduleName);
}
auEvent.setAuModule(auModule);
// optioanlly you can call here - auEventDao.merge(auEvent);
}

关于java - JPA 分离实体传递到持久化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17362605/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com