[英]JPA detached entity passed to persist
I have a DAO with @Transactional
annotation and with EntityManager
inside. 我有一个带有@Transactional
批注和内部EntityManager
的DAO。
Also I have a some IOC managed bean that has one transactional method inside. 我也有一些IOC托管的bean,其中包含一种事务方法。
And there are 2 entities with uni directional many2one - 并且有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 doesnt have reference on AuEvents
AuModule在AuEvents
上没有引用
I'm trying to do like this 我正在尝试这样做
@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]
}
As I read in https://stackoverflow.com/questions/14057333/detached-entity-passed-to-persist-error-with-onetomany-relation I tried to do in this way 当我在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]
}
SO, does anyone know how I can avoid this? 所以,有人知道我能避免这种情况吗? PS Please don't suggest me to write DAO method like that - 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);
}
I exactly want to save event&module not inside of any DAO 我完全想保存事件和模块不在任何DAO内
Thanks 谢谢
In the second example, you should not call auEventDao.persist(auEvent);
在第二个示例中,不应调用auEventDao.persist(auEvent);
in the end. 到底。 auEvent
is already attached so its enough that your transaction just ends. auEvent
已被附加 ,以至于您的交易刚刚结束。
Also you shouldn't call persist()
on object which is allready persistent. 同样,您不应该在已经持久的对象上调用persist()
。 You should call it only on new objects. 您应该仅在新对象上调用它。 That's also the problem in your first example. 这也是您第一个示例中的问题。
You call persist()
only once on auEvent
that's right. 您只需要在正确的auEvent
上调用一次persist()
。 But sometimes there's existing (already persisted, found in DB) auModule
associated with this auEvent
. 但是有时存在与此auEvent
相关联的现有auModule
(已在数据库中找到,已经存在)。 And you marked this association with CascadeType.PERSIST
. 您用CascadeType.PERSIST
标记了此关联。 So persist()
is cascaded also to existing auModule
-> exception thrown . 因此, persist()
也级联到现有的auModule
> thrown异常 。
Something like this should work: 这样的事情应该起作用:
1. 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);
}
or 要么
2. 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);
}
In the onEvent() method you did not set the AuModule in the AuEvent after the if as you did in the saveEvent() method. 在onEvent()方法中,您没有像在saveEvent()方法中那样在if之后设置AuEvent中的AuModule。
I hope this helps. 我希望这有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.