2011-12-24 28 views
16

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(); 
    } 
} 

私は、JSFのWebアプリでPersonManager 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> 

問題は、PersonLocal EJBの注入が起こらないということです。 personプロパティは常にNULLです。何が間違っていたのですか?

しかし、私はこのようにJSF管理対象BeanにPersonManagerを注入した場合:

ITワークス
@ManagedBean 
@RequestScoped 
public class Index { 
    @EJB 
    private PersonManagerLocal personManager; 
    .... 

。最初のシナリオが必要です.-D

+0

?注釈が発明されなかったときに過去に戻ろうとするようなものです:P –

+0

あなたは正しいです:-それは理論上のものです。答えを知りたいのですが。 – Forty

+0

@Fortyそれではなぜ機能しないのですか?その答えは私には分かりません。 –

答えて

37

EJBとJSFマネージドBeanの責任が混在しています。 faces-config.xmlには、EJBではなくマネージドBeanなどのJSF成果物のみが登録されます。 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}によりビューで使用可能ですBeanを管理して、あなたがクラスを登録していません。これは、EJBコンテナによって管理されるのと同じインスタンスを表しません。 ではなく、を使用して faces-config.xmlを使用してEJBを登録することができます。ここで @Stateless@Statefulのような javax.ejbパッケージのアノテーションを使用します。これで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):あなたは@EJBアノテーションを使用の代わりに、手動でのfaces-config.xmlにそれを宣言していないのはなぜ

@Stateless 
public class PersonService { 

    @PersistenceContext 
    private EntityManager em; 

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

    // ... 
} 
+0

ありがとう、PersonManagerはビジネスEJBであるため、@ ManagedBeanアノテーションは含まれていません。これはJSFエンジンによって作成され、faces-configシナリオの下でpersonというEJBをそれに注入しません。 – Forty

+0

私は、どのようなEJBが使用されているのか、どのように使用されているのかを知っています。あなたは?どの部分が正確にまだ不明な部分がありますか? – BalusC

+4

私の答えの例では '@ Stateful'がありません。 **これはEJBではありません**。 EJBをJSF管理Beanとして悪用しようとしていました。これは正しくない。基本的には、ビューとして1つのXHTMLファイル、コントローラとして1 JSFマネージドBean、モデルとして1エンティティ、サービスとして1 EJBが必要です。あなたの質問では、 'PersonManager'はEJBでなくJSFマネージドBeanでなければなりません。 'PersonLocal'はエンティティではなく、EJBであると思われます。だから、本当にEJBである必要があるかどうかは疑問です。 EJBは、 'create()'、 'save()'などのサービスを提供するよう意図されています。 – BalusC

関連する問題