лицо управления сохраняются - PullRequest
1 голос
/ 04 августа 2010

У меня проблема при попытке обновить внешние ключи. Используя функцию слияния, я всегда получаю сообщение об ошибке нехватки памяти или получаю тайм-аут

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

что я делаю не так? Есть ли лучший способ сделать это?

1 Ответ

1 голос
/ 07 августа 2010

Проблема заключалась в том, что у меня уже были все объекты в отсоединенном состоянии, и выполнение поиска привело к загрузке всего дерева объектов еще раз.

Использование 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): послеобъединить отсоединенный объект (raum) не имеет обновленного поля версии, поэтому выполнение нового обновления вызовет исключение, и мне пришлось исправить это, увеличив поле версии в моем методе

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это скорее хак, но ... это работает, и я не смог найти лучшего решения, учитывая, что этот код предназначен для веб-сайта, где работа с отдельными экземплярами является лучшим решением (создание дерева объектов занимает много времени, и яне хочу воссоздавать все с каждым запросом)

...