Хотелось бы услышать экспертов по лучшей практике редактирования сущностей JPA из пользовательского интерфейса JSF.
Итак, пара слов о проблеме.
Представьте, что у меня есть постоянный объект MyEntity
, и я выбираю его для редактирования. В слое DAO я использую
return em.find(MyEntity.class, id);
Возвращает экземпляр MyEntity
с прокси на «родительских» объектах - представьте, что одним из них является MyParent
. MyParent
извлекается как приветствие прокси на @Access(AccessType.PROPERTY)
:
@Entity
public class MyParent {
@Id
@Access(AccessType.PROPERTY)
private Long id;
//...
}
и 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
.
Расширенный контекст персистентности мне не подходит.
Спасибо!