Java JPA分离实体传递到持久化
我有一个带有Java JPA分离实体传递到持久化,java,spring,jpa,Java,Spring,Jpa,我有一个带有@Transactional注释和EntityManager内部的DAO 我还有一个IOC管理的bean,它内部有一个事务方法 并且有2个实体具有单向MANYOne- @Entity @Table(name = "AU_EVENT") public class AuEvent { @ManyToOne(fetch= FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE}) @JoinColumn(
@Transactional
注释和EntityManager
内部的DAO
我还有一个IOC管理的bean,它内部有一个事务方法
并且有2个实体具有单向MANYOne-
@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]
}
当我阅读时,我试着这样做
@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请不要建议我这样写刀法-
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中
感谢您在onEvent()方法中没有像在saveEvent()方法中那样在if之后的AuEvent中设置AuModule
我希望这会有所帮助。在onEvent()方法中,您没有像在saveEvent()方法中那样在if之后的AuEvent中设置AuModule
我希望这有帮助。在第二个示例中,您不应该调用
auevendao.persist(auEvent)代码>最后<代码>auEvent
已附加,因此您的交易仅需结束即可。另外,您不应该对allready persistent对象调用
persist()
。您应该只在新对象上调用它。这也是您第一个示例中的问题
在auEvent
上只调用一次persist()。但有时存在与此auEvent
关联的现有(已持久化,在DB中找到)的auModule
。您将此关联标记为CascadeType.PERSIST
。因此,persist()
也被级联到现有的auModule
->抛出的异常
类似这样的方法应该会奏效:
一,
或
2.
在第二个示例中,您不应该调用auevendao.persist(auEvent)代码>最后<代码>auEvent
已附加,因此您的交易仅需结束即可。
另外,您不应该对allready persistent对象调用persist()
。您应该只在新对象上调用它。这也是您第一个示例中的问题
在auEvent
上只调用一次persist()。但有时存在与此auEvent
关联的现有(已持久化,在DB中找到)的auModule
。您将此关联标记为CascadeType.PERSIST
。因此,persist()
也被级联到现有的auModule
->抛出的异常
类似这样的方法应该会奏效:
一,
或
2.
很抱歉,这是我的错误-我没有写它,因为我必须调整我的代码-这是一个商业项目。我再次道歉。我很抱歉这是我的错误-我没有写它,因为我必须调整我的代码-这是一个商业项目。我再次道歉,谢谢你的帮助!但是我在1和2之间看到的唯一区别是对DAO.merge()的调用。。。我不敢相信,若我并没有调用merge(第二个变体),auModule会被保存到DB中……它应该可以工作,auEvent实体附在这里,请参见-。我更喜欢第一个选项,显式调用merge。@OndrejBozek如果提供程序足够聪明,可以执行持久化,然后执行合并,那就太好了。谢谢您的帮助!但是我在1和2之间看到的唯一区别是对DAO.merge()的调用。。。我不敢相信,若我并没有调用merge(第二个变体),auModule会被保存到DB中……它应该可以工作,auEvent实体附在这里,请参见-。我更喜欢第一个选项,显式调用merge。@OndrejBozek如果提供程序足够聪明,可以执行persist,然后执行merge,那就好了。
@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);
}
@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);
}