Вы смешиваете обязанности 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);
}
// ...
}