Я работаю над веб-приложением на основе Wicket на Java EE.
Я пытаюсь найти способ гарантировать, что любые объекты, используемые в качестве объектов модели, всегда привязаны к текущему EntityManager, прежде чем Wicket попытается отобразить любые компоненты. Таким образом, когда компоненты захватывают данные из своей модели, данные могут быть лениво загружены сущностью по мере необходимости.
Здесь есть много обучающих программ и некоторые сообщения здесь, ссылаясь на LoadableDetachableModels (LDM) в качестве решения. Это сработало для нас, когда нам не нужно сохранять какие-либо промежуточные запросы. В этих случаях, всякий раз, когда страница отображается, LDM загружает самую последнюю версию требуемого объекта из базы данных.
Тем не менее, бывают случаи, когда пользователю необходимо редактировать данные в форме состояния через несколько шагов, прежде чем она сохранит данные, поэтому модели необходимо сохранить объект в состоянии "несохраненного". LDM эффективно уничтожит изменения пользователя на каждом шаге.
До сих пор мы использовали модель, которая при необходимости объединяет объект с контекстом персистентности. Вот упрощенная версия:
public final class DetachableMergingModel<E extends Identifiable> implements IModel<E> {
private E entity;
private boolean attached = false;
public DetachableMergingModel(E entity) {
this.entity = entity;
}
@Override
public E getObject() {
if (!attached) {
attached = true;
// Non-transactional method merges entity with persistence context
// but does not flush any data to database
entity = getRepository().merge(entity);
}
}
return entity;
}
@Override
public void setObject(E entity) {
this.entity = entity;
}
@Override
public void detach() {
// This ensures that the next call to getObject() will merge the entity with
// the persistence context
attached = false;
}
/* ... */
}
Наш EntityManager вводится GlassFish, и он охватывает весь запрос сервлета, поэтому, когда объект привязан к контексту персистентности, он будет оставаться прикрепленным до тех пор, пока страница не будет отображаться.
В приведенной выше модели рассматриваются ситуации, когда объект уже сохраняется и только что редактируется. Всякий раз, когда компонент на странице вызывает getObject() в этой модели, модель объединяет объект с контекстом персистентности, и мы можем перемещаться по всему объектно-ориентированному объекту без металирования любых LazyInitializationExceptions.
Однако в ситуации, когда объект является новым и не был сохранен, мы не можем использовать эту модель, потому что сущность еще не готова к объединению. Это часто бывает, когда пользователь создает новый объект и все равно должен заполнить его значениями через форму. В этом случае мы хотим иметь такую же свободу навигации по объектно-ориентированному объекту (поскольку некоторые ассоциации уже установлены, например родительский объект), не опасаясь исключения LazyInitializationException.
Аналогичное решение описывается здесь (вариант № 3), но оно не распространяется на прецедентный вариант "нового объекта", описанный выше.
Кто-нибудь сталкивался с этим прецедентом? Как вы его решили? Есть ли лучший способ интегрировать Wicket с JPA, чем с помощью пользовательских реализаций IModel?