Инъекция JJF в управляемый боб EJB - PullRequest
18 голосов
/ 24 декабря 2011

У меня есть EJB (PersonManager) в модуле Enterprise Application, который вводит другой EJB (Person):

@Stateful
public class PersonManager implements PersonManagerLocal {
    @EJB
    private PersonLocal person;

    @Override
    public void setPersonName(String name) {
        person.setName(name);
    }

    @Override
    public String getPersonName() {
        return person.getName();
    }
}

Я хочу использовать PersonManager EJB в веб-приложении JSF. Я определяю это в face-config.xml:

<managed-bean>
    <managed-bean-name>personManager</managed-bean-name>
    <managed-bean-class>ejb.PersonManager</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

Проблема в том, что инъекция PersonLocal EJB не происходит. Свойство person всегда NULL. Что я не прав?

Но если я внедряю PersonManager в управляемый JSF-компонент следующим образом:

@ManagedBean
@RequestScoped
public class Index {
    @EJB
    private PersonManagerLocal personManager;
    ....

ЭТО РАБОТАЕТ. Мне нужен первый сценарий, пожалуйста, помогите мне: -D

1 Ответ

40 голосов
/ 25 декабря 2011

Вы смешиваете обязанности EJB и управляемых компонентов JSF. faces-config.xml регистрирует только артефакты JSF, такие как управляемые bean-компоненты, а не EJB. Ваша регистрация в faces-config.xml

<managed-bean>
    <managed-bean-name>personManager</managed-bean-name>
    <managed-bean-class>ejb.PersonManager</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

делает то же самое, что и

@ManagedBean
@SessionScoped
public class PersonManager {
    // ...
}

Другими словами, вы регистрируете класс как управляемый компонент JSF, который доступен в представлениях по #{personManager}. Это не тот же экземпляр, которым управляет контейнер EJB. Вы можете и должны не использовать faces-config.xml для регистрации EJB. Там вы используете аннотации из пакета javax.ejb, например @Stateless и @Stateful. Это все, что вам нужно, чтобы зарегистрировать EJB.

На самом деле регистрация управляемых компонентов JSF в faces-config.xml - это старый способ JSF 1.x, который в JSF 2.x заменен новой аннотацией @ManagedBean.


Обновление правильный подход будет:

Просмотр (файл Facelets):

<h:form>
    <h:inputText value="#{personManager.person.name}" />
    ...
    <h:commandButton value="Save" action="#{personManager.save}" />
    <h:messages />
</h:form>

Контроллер (управляемый компонент JSF):

@ManagedBean
@ViewScoped
public class PersonManager implements Serializable {

    private Person person;

    @EJB
    private PersonService personService;

    @PostConstruct
    public void init() {
        person = new Person();
    }

    public void save() {
        personService.create(person);
        FacesContext.getCurrentInstance().addMessage(null,
            new FacesMessage("Person successfully created, new ID is " + person.getId()));
    }

    // ...
}

Модель (объект JPA):

@Entity
public class Person implements Serializable {

    @Id
    private Long id;

    private String name;

    // ...
}

Сервис (EJB без сохранения состояния):

@Stateless
public class PersonService {

    @PersistenceContext
    private EntityManager em;

    public void create(Person person) {
        em.persist(person);
    }

    // ...
}
...