实体管理器坚持

发布于 2024-09-12 23:55:57 字数 1154 浏览 4 评论 0原文

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

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 = ?

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

I have a problem when trying to update foreign keys.
Using the merge function I always get a out of memory error, or I get a timeout

Fakultaet and Standort are foreign keys in the Raum table (many to one, and lazy fetching)
Raum does eager fetching for the Fakultaet and 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);
 }
 ....
}

I then tried using getReference() instead of find() since I only want to do an update,
so I have the method:

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

still not working
afterwards I removed the s.getRaums().add(r) and f.getRaums().add(r) lines
but this causes a LazyInitializationException in the next query I need to do.

all I want is something like this:

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

what am I doing wrong ? is there a better method of doing this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

暮倦 2024-09-19 23:55:57

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

使用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;
 }
}

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

The problem was that I already had all the objects in a detached state and doing a find caused the entire object tree to be loaded once more.

Using em.getReference didn't solve the problem because accessing any of the attributes of the object caused it to be loaded, so it had the same problem as find.

the solution is to only use the detached instances
the new merge function looks something like this:

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

where all the parameters are detached instances.

This still has a problem (at least for me and my hibernate version 3.2):
after merge the detached object (raum) doesn't have it's version field updated, so doing a new update will cause an exception, and I had to fix this by incrementing the version field in my method

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

This is more of a hack but... it works and I couldn't find a better solution considering that this code is for a website, where working with detached instances is the best solution (creating the object tree takes a lot of time and I don't want to recreate everything with every request)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文