简体   繁体   English

JPA独立实体已传递以保留

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM