2010-08-04 1 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() вместо находку(), так как я только хочу, чтобы сделать обновление, поэтому у меня есть метод:

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) lines , но это вызывает исключение LazyInitializationException в следующем запросе, который мне нужно сделать.

все, что я хочу что-то вроде этого:

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

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

ответ

1

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

Использование 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); 
} 

, где все параметры отдельные экземпляры.

У этой проблемы все еще есть проблема (по крайней мере, для меня и моей версии спящего режима 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; 
} 
} 

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