2010-08-04 59 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; 
} 
} 

这更是一个黑客,但...它的作品,我无法找到一个更好的解决方案考虑到这个代码是一个网站递增版本字段来解决这个问题,在哪里使用分离的实例是最好的解决方案(创建对象树需要大量的时间,我不想重新创建每个请求的所有内容)