gpt4 book ai didi

java - 实体管理器坚持

转载 作者:太空宇宙 更新时间:2023-11-04 08:50:42 24 4
gpt4 key购买 nike

我在尝试更新外键时遇到问题。使用合并功能我总是遇到内存不足错误,或者超时

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);
}

仍然无法工作
之后我删除了 s.getRaums().add(r) 和 f.getRaums().add(r) 行但这会导致我需要执行的下一个查询中出现 LazyInitializationException。

我想要的就是这样的:

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

我做错了什么?有更好的方法吗?

最佳答案

问题是我已经让所有对象处于分离状态,并且执行查找导致整个对象树再次加载。

使用em.getReference并没有解决问题,因为访问对象的任何属性都会导致它被加载,所以它与find有同样的问题。

解决方案是仅使用分离的实例
新的合并函数看起来像这样:

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);
}

其中所有参数都是分离的实例。

这仍然有一个问题(至少对于我和我的 hibernate 版本 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;
}
}

这更像是一种黑客攻击,但是......它有效,考虑到此代码适用于网站,我找不到更好的解决方案,其中使用独立实例是最佳解决方案(创建对象树需要大量时间,我不想为每个请求重新创建所有内容)

关于java - 实体管理器坚持,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3404129/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com