我有一个带有@Transactional
注释且里面有EntityManager
的DAO。
我还有一个IOC托管bean,里面有一个事务方法。
并且有2个实体具有单向多数2 -
@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中的事件和模块
由于
答案 0 :(得分:1)
在第二个示例中,您不应该最后调用auEventDao.persist(auEvent);
。 auEvent
已经附加,因此足以让您的交易结束
此外,你不应该在已经持久的对象上调用persist()
。你应该只在新对象上调用它。这也是你的第一个例子中的问题。
您只能在persist()
上拨打auEvent
一次,这是正确的。但有时存在(已在数据库中保留,已在数据库中找到)auModule
与此auEvent
相关联。并且您将此关联标记为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);
}
答案 1 :(得分:0)
在onEvent()方法中,你没有像在saveEvent()方法中那样在if后面的AuEvent中设置AuModule。
我希望这会有所帮助。