您正在混合 EJB 和 JSF 托管 Bean 的职责。这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 托管 bean,可以通过以下方式在视图中使用该 bean:#{personManager}
。这并不代表 EJB 容器管理的同一实例。你可以而且应该not use faces-config.xml
注册 EJB。在那里您可以使用来自javax.ejb
包用于,例如@Stateless
and @Stateful
。这就是注册 EJB 所需的全部内容。
实际上,在中注册 JSF 托管 beanfaces-config.xml
是旧的 JSF 1.x 方式,在 JSF 2.x 中已被新的方式取代@ManagedBean
注解。
Update正确的方法是:
查看(Facelets 文件):
<h:form>
<h:inputText value="#{personManager.person.name}" />
...
<h:commandButton value="Save" action="#{personManager.save}" />
<h:messages />
</h:form>
控制器(JSF 托管 bean):
@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);
}
// ...
}