2013-06-28 115 views
1

我有一個DAO與@Transactional註釋和EntityManager裏面。JPA獨立實體傳遞到持久

另外我有一個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的

感謝

回答

1

在第二個示例中,最後不應該調用auEventDao.persist(auEvent);auEvent已經是附加所以它足以讓您的交易結束。
另外你不應該在對象上調用persist()這是持久性的。你應該只在新對象上調用它。這也是你的第一個例子中的問題。

您只需在auEvent上撥打persist()即可。但是有時候存在(已經存在,在DB中找到)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); 
} 
+0

感謝您的幫助!但唯一的區別是我看到1和2之間 - 是DAO.merge()的調用...我不相信如果我沒有調用合併(第二個變體)auModule會被保存到DB ... – Olegdelone

+0

它應該工作,auEvent實體*附加*請參閱 - http://stackoverflow.com/questions/1069992/jpa-entitymanager-why-use-persist-over-merge。我寧願選擇第一個選項,明確地調用合併。 –

+0

不可思議!所以第一個變體的作品!你很酷。 – Olegdelone

0

在的onEvent()方法您沒有像在SaveEvent()方法中那樣在if後設置AuEvent中的AuModule。

我希望這會有所幫助。

+0

對不起,這是我的錯 - 我沒有寫,因爲我不得不溫和我的代碼 - 這是一個商業projetc。我再次道歉。 – Olegdelone

相關問題