Как разделить сущность между компонентами поддержки 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 и вставьте их друг в друга, как вам нужно.

Другие вопросы по тегам