2011-12-24 257 views
16

我在企業應用MODUL的EJB(的PersonManager)中注入另一個EJB(人):JSF託管bean EJB注入

@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的Web應用程序。我在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> 

問題是,PersonLocal EJB的注入不會發生。 person屬性始終爲NULL。我錯了什麼?

但如果我注入的PersonManager在JSF管理的bean這樣的:

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

它的作品。我需要第一種方案,請幫助我:-D

+0

你爲什麼不使用@EJB註解,而不是手動faces-config.xml中聲明它?這就像在註釋未被髮明時試圖回到過去:P – 2011-12-24 19:36:48

+0

你是對的: - 它只是理論上的,我想知道答案。 – Forty 2011-12-24 20:45:50

+0

@Forty那麼爲什麼它不工作?答案並不清楚。 – 2013-06-19 17:35:56

回答

37

您正在混合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是在視圖中提供的#{personManager}。這不代表與EJB容器管理的實例相同的實例。您可以並應該而不是使用faces-config.xml來註冊EJB。在那裏,您使用javax.ejb數據包的註釋,例如@Stateless@Stateful。這就是您需要註冊EJB的全部內容。

實際上,在faces-config.xml中註冊JSF託管的bean是一種舊的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的託管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); 
    } 

    // ... 
} 
+0

謝謝,PersonManager是一個商業EJB,因此不包含@ManagedBean註釋。它由JSF引擎創建,只是在faces-config場景下不會將EJB注入到它中。 – Forty 2011-12-25 07:23:12

+0

我知道EJB是什麼以及它們應該如何使用。你做?究竟哪一部分現在還不清楚? – BalusC 2011-12-25 12:42:43

+4

請注意,我的答案示例中缺少'@ Stateful'。這不是**這樣的EJB。您試圖將EJB作爲JSF受管bean進行濫用。這個不對。基本上你應該有1個XHTML文件作爲View,1個JSF託管bean作爲Controller,1個實體作爲Model,1個EJB作爲服務。在你的問題中,PersonManager應該是一個JSF託管bean,而不是EJB。 PersonLocal似乎太多實體,而不是EJB。所以我懷疑它是否真的需要成爲一個EJB。 EJB可以提供諸如'create()','save()'等服務。 – BalusC 2011-12-25 16:29:08