2010-08-04 60 views
1

嘗試更新外鍵時遇到問題。使用合併功能 我總是得到一個內存不足的錯誤,或者我得到一個超時entitymanager persist

Fakultaet和Standort外鍵在RAUM表(多對一,並延遲抓取) RAUM確實渴望獲取的Fakultaet和Standort

@Stateless 
@Local (IRaumHomeLocal.class) 
@Remote (IRaumHomeRemote.class) 
public class RaumHome implements IRaumHome { 
@PersistenceContext private EntityManager em; 

void merge(Raum r, Integer fid, Integer sid) { 
    Fakultaet f = em.find(Fakultaet.class, fid); 
    Standort s = em.find(Standort.class, sid); 
    r.setFakultaet(f); 
    r.setStandort(s); 
    f.getRaums().add(r); 
    s.getRaums().add(r); 
    em.merge(r); 
} 
.... 
} 

我然後使用getReference()代替find()方法,因爲我只想做一個更新嘗試, 所以我有方法:

void merge(Raum r, Integer fid, Integer sid) { 
Standort s = em.getReference(Standort.class, sid); 
Fakultaet f = em.getReference(Fakultaet.class, fid); 
s.getRaums().add(r); // now it lags here 
f.getRaums().add(r); 
em.merge(r); 
} 

仍不worki ng
之後我刪除了s.getRaums().add(r)和f.getRaums().add(r)行 ,但是這會在我需要做的下一個查詢中導致LazyInitializationException。

我要的是這樣的:

UPDATE Raum SET FakultaetId = ?, StandortId = ? WHERE RaumID = ? 

我究竟做錯了什麼?有沒有更好的方法來做到這一點?

回答

1

問題是我已經擁有了處於分離狀態的所有對象,並且執行了查找操作,導致整個對象樹再次被加載。

使用em.getReference沒有解決問題,因爲訪問該對象的任何屬性導致它被加載,所以它有與查找相同的問題。

的解決方案是隻使用分離的情況下
新的合併功能看起來是這樣的:

void merge(Raum r, Fakultaet f, Standort s) { 
r.setFakultaet(f); 
r.setStandort(s); 
f.getRaums().add(r); 
s.getRaums().add(r); 
em.merge(r); 
} 

,所有的參數都分離的情況。

這仍然有一個問題(至少對我和我的休眠版本3.2): 合併後分離的對象(r​​aum)沒有它的版本字段更新,所以做一個新的更新將導致異常,並我曾在我的方法

void merge(Raum r, Fakultaet f, Standort s) { 
try { 
    r.setFakultaet(f); 
    r.setStandort(s); 
    f.getRaums().add(r); 
    s.getRaums().add(r); 
    em.merge(r); 
    r.setVersion(r.getVersion() + 1); 
} 
catch(RuntimeException re) { 
    // logging 
    throw re; 
} 
} 

這更是一個黑客,但...它的作品,我無法找到一個更好的解決方案考慮到這個代碼是一個網站遞增版本字段來解決這個問題,在哪裏使用分離的實例是最好的解決方案(創建對象樹需要大量的時間,我不想重新創建每個請求的所有內容)