Хотел бы услышать экспертов по передовому опыту редактирования сущностей JPA из пользовательского интерфейса JSF.
Итак, пару слов о проблеме.
Представьте, что у меня есть постоянный объект MyEntity
и беру его для редактирования. На уровне DAO я использую
return em.find(MyEntity.class, id);
, который возвращает экземпляр MyEntity
с прокси на «родительских» объектах - представьте, что один из них - MyParent
. MyParent
выбирается как прокси-приветствие для (скрытого) MyEntity, имеющего ссылку на него:
@ManyToOne(fetch = FetchType.LAZY)
@LazyToOne(LazyToOneOption.PROXY)
private MyParent myParent;
Пока все в порядке. В пользовательском интерфейсе я просто использую выбранный объект напрямую, без создания каких-либо объектов значений, и использую родительский объект в списке выбора:
<h:selectOneMenu value="#{myEntity.myParent.id}" id="office">
<f:selectItems value="#{parents}"/>
</h:selectOneMenu>
Все отображается нормально, нет LazyInitializationException
. Но когда я сохраняю объект, я получаю
LazyInitializationException: could not initialize proxy - no Session
в методе MyParent
прокси setId ()
.
Я могу легко решить проблему, если изменю MyParent
к EAGER
@ManyToOne(fetch = FetchType.EAGER)
private MyParent myParent;
или получить объект, используя left join fetch p.myParent
(на самом деле, как я сейчас это делаю). В этом случае операция сохранения работает нормально, и отношение прозрачно меняется на новый объект MyParent
. Никаких дополнительных действий (ручное копирование, ручная настройка ссылок) выполнять не нужно. Очень просто и удобно.
НО . Если объект ссылается на 10 других объектов - em.find ()
приведет к 10 дополнительным соединениям , что не является хорошей операцией с базой данных, особенно когда я не использовать ссылки на состояние объектов вообще . Все, что мне нужно, - это ссылки на объекты, а не их состояние.
Это глобальная проблема, я хотел бы знать, как специалисты JSF работают с объектами JPA в своих приложениях, что является лучшей стратегией, позволяющей избежать лишних объединений и LazyInitializationException
.
Расширенный контекст персистентности мне не подходит.
Спасибо!