2013-07-16 34 views
0

我有兩個表之間的關係OneToOne,如下所示:OneToOne關係並不總是取

PreRecordLoad.java:

@OneToOne(mappedBy="preRecordLoadId",cascade = CascadeType.ALL) 
private PreRecordLoadAux preRecordLoadAux; 

PreRecordLoadAux.java:

@JoinColumn(name = "PRE_RECORD_LOAD_ID", referencedColumnName = "PRE_RECORD_LOAD_ID") 
@OneToOne 
private PreRecordLoad preRecordLoadId; 

我使用此方法撤回PreRecordLoad對象:

public PreRecordLoad FindPreRecordLoad(Long ID) 
{ 
    print("Finding " + ID + "f"); 

    Query query; 
    PreRecordLoad result = null; 
    try 
    { 
     query = em.createNamedQuery("PreRecordLoad.findByPreRecordLoadId"); 
     query.setParameter("preRecordLoadId", ID); 
     result = (PreRecordLoad)query.getSingleResult(); 
     //result = em.find(PreRecordLoad.class, ID); 
    } 
    catch(Exception e) 
    { 
     print(e.getLocalizedMessage()); 
    } 

    return result; 
} 

'+'f''是爲了查看傳遞的值是否在某種程度上有某種結果。它沒有。

我最初使用em.find,但無論使用哪種方法都會發生同樣的問題。

我以前使用BigDecimal作爲ID,因爲它是默認的,並且注意到當它工作時,以及何時不起作用時,我得到了精度差異。具體來說,精確度爲4,否則爲0。我無法弄清楚爲什麼會出現這種情況,所以我將BigDecimal更改爲Long,因爲無論如何我從來都不需要它成爲BigDecimal。

當我將新的PreRecordLoad和PreRecordLoadAux對象保存到數據庫(第一次插入它們)時,然後嘗試運行此方法來調用對象時,它將檢索PreRecordLoad,但PreRecordLoadAux爲null。儘管入口在數據庫中,而且看起來完全被提交,因爲我可以從SQLDeveloper(這是一個單獨的會話)訪問它。

但是,如果我停止並重新運行該應用程序,則它會成功撤回這兩個對象。所傳遞的ID兩次都是相同的,或者至少看起來是這樣。

無論如何建議將不勝感激,謝謝。

編輯:

這是當我堅持的對象到數據庫的代碼:

if(existingPreAux==null) { 
     try { 
      preLoad.setAuditSubLoadId(auditLoad); 
      em.persist(preLoad); 
      print("Pre Record Load entry Created"); 

      preAux.setPreRecordLoadId(preLoad); 
      em.persist(preAux); 
      print("Pre Record Load Aux entry Created"); 
     } 
     catch(ConstraintViolationException e) { 
      for(ConstraintViolation c : e.getConstraintViolations()) { 
       System.out.println (c.getPropertyPath() + " " + c.getMessage()); 
      } 
     } 
    } 
    else { 
     try { 
      preLoad.setPreRecordLoadId(existingPreLoad.getPreRecordLoadId()); 
      preLoad.setAuditSubLoadId(auditLoad); 
      em.merge(preLoad); 
      print("Pre Record Load entry found and updated"); 

      preAux.setPreRecordLoadAuxId(existingPreAux.getPreRecordLoadAuxId()); 
      preAux.setPreRecordLoadId(preLoad); 
      em.merge(preAux); 
      print("Pre Record Load Aux entry found and updated"); 
     } 
     catch(ConstraintViolationException e) { 
      for(ConstraintViolation c : e.getConstraintViolations()) { 
       System.out.println (c.getPropertyPath() + " " + c.getMessage()); 
      } 
     } 
    } 

這是一個方法,而該代碼後,該方法結束。

+1

我沒有看到更多的前2行,但我可以說,映射是錯誤的alreay。如果你有一個OneToOne,你必須在另一邊有OneToOne。如果你有一個ManyToOne,你必須在另一邊有一個OneToMany。另外,尊重Java命名約定。 –

+0

@JB Nizet哦,上帝,真是個白癡。但是,我沒有注意到我有一個ManyToOne和OneToOne * facepalm *。謝謝,我會改變它。儘管我很害怕,但我仍然得到同樣的錯誤。我將更新問題代碼。 – MasNotsram

+0

向我們展示更多您的代碼。我的猜測是你堅持並在同一事務中加載對象,並忽略初始化關聯的兩端。如果您尚未初始化雙方,則會從第一級緩存中獲取不正確的對象。 –

回答

1

維護對象圖的連貫性是您的責任。所以,當你做preAux.setPreRecordLoadId(preLoad);時,喲也必須做preLoad.setPreRecordLoadAux(preAux);

如果不這樣做,那麼每當您從同一個會話中加載preAux時,它將從第一級緩存中檢索,並因此返回您實體的錯誤初始化實例。

+0

完美。非常感謝你。 – MasNotsram