Как разделить сущность между компонентами поддержки JSF?
Я хотел бы модулировать мое приложение JSF 2.1 / Java EE. У меня есть страница, которая состоит из нескольких модулей. Каждый модуль должен использовать отдельный компонент поддержки JSF. Некоторые из этих модулей должны показывать и изменять некоторые данные из одной и той же сущности.
Я уже попробовал некоторые подходы, но я не удовлетворен до сих пор. Я спрашиваю себя, как лучше всего это сделать?
Все модули используют одну и ту же сущность, и они (вероятно) должны уведомить другие компоненты поддержки, если некоторые данные изменились.
Комментарии к некоторым подходам, которые я уже попробовал:
- Передача объекта в мой компонент (XHTML) через интерфейс также не передаст его компоненту поддержки.
- Загрузка сущности в методе bean-компонента postContruct путем считывания идентификатора из параметров запроса обычно не рекомендуется в пользу использования подхода "viewParam"
- Использование "viewParam" ИМХО не так хорошо, как наличие сущности после создания бина (в моем postConstruct). Я не уверен, когда вызывается установщик бина.
2 ответа
Несмотря на то, что это "обычно не одобряется" (кем?), Я использую один из следующих методов в моих компонентах поддержки JSF-2.2 (в зависимости от того, нужно ли мне personId
для чего-то другого)
@ViewScoped
public class BeanConverter {
@Inject @Param(name = "personId")
private ParamValue<Person> curPerson;
}
@ViewScoped
public class BeanConstruct {
@PersistenceContext
private EntityManager em;
@Inject @Param
private ParamValue<Long> personId;
private Person curPerson;
@PostConstruct
public void init() {
curPerson = em.find(Person.class, personId.getValue());
}
}
Это использует превосходную поддержку CDI Omnifaces. Я тогда использую merge()
обновить сущность, но в моем случае только один компонент получает для сохранения изменений в сущности, поэтому YMMV. Когда бинам необходимо сообщать обновления или создания сущностей между собой, я обычно javax.enterprise.Event
где событие получает сущность в качестве аргумента конструктора:
public class BeanSending {
@Inject
private Event<PersonCreated> personCreatedEvent;
public void constructPerson() {
Person person = makePerson();
personCreatedEvent.fire(new PersonCreated(person));
}
}
public class BeanUpdater {
public void updatePerson(@Observes PersonCreated evt) {
doStuffWithPerson(evt.getPerson());
}
}
Я думаю, что вам нужен CDI - инъекция контекста и зависимости. Просто нарежьте свою страницу на несколько небольших бобов CDI и вставьте их друг в друга, как вам нужно.