2012-01-06 9 views
0

私のアプリには奇妙な振る舞いがあります。 私はSessionScope Bean(Bean A)を使ってユーザーの設定を保持しています。 RequestScopeにある私の他のBean(Bean B)では、私はSessionScope beanを注入します。JSF2/CDIで更新された他のSessionScoped Beanの前に@PostConstructが呼び出されましたか?

Bean Bには、Bean Aの値に応じてデータベースから値のリストを取得するための@PostConstructメソッドがあります。ユーザーがBean Aの値を変更し、Bean Bの値が正しくないとアプリケーションが混乱します@PostConstructメソッドが呼び出された時点で私はログでそれをテストしました。

私はすべてのセッターメソッドがアプリケーションフェーズを呼び出す前に更新されると思いますか?あなたが見ることができるように

ba: BankAccount [accountId=123456789, bankName=Ing DiBa, blz=50010517] 
retrieveAllSubAccount: BankAccount [accountId=123456789, bankName=Ing DiBa, blz=50010517] 
retrieveAllSubAccount: BankAccount [accountId=123456789, bankName=Ing DiBa, blz=50010517] 
ba: BankAccount [accountId=987654321, bankName=Barclaycard Barclays Bank, blz=20130600] 

..:

ビーンA:

@Named 
@SessionScoped 
public class SessionBean implements Serializable { 
private static final long serialVersionUID = -4214048619877179708L; 

@Inject private Logger log; 
private BankAccount selectedBankAccount; 

public BankAccount getSelectedBankAccount() { 
    return selectedBankAccount; 
} 

public void setSelectedBankAccount(BankAccount selectedBankAccount) { 
    log.info("ba: " + selectedBankAccount); 
    this.selectedBankAccount = selectedBankAccount; 
} 

ビーンB:

@RequestScoped 
public class SubAccountListProducer { 
    @Inject private SessionBean sessionBean; 
    @Inject private EntityManager em; 

@PostConstruct 
public void retrieveAllSubAccount() { 
    CriteriaBuilder cb = em.getCriteriaBuilder(); 
    CriteriaQuery<SubAccount> criteria = cb.createQuery(SubAccount.class); 
    Root<SubAccount> account = criteria.from(SubAccount.class); 
    log.info("retrieveAllSubAccount: " + sessionBean.getSelectedBankAccount()); 
    criteria.select(account).where(cb.equal(account.get("bankAccount"), sessionBean.getSelectedBankAccount())); 
    criteria.select(account).orderBy(cb.desc(account.get("name"))); 
    entityList = em.createQuery(criteria).getResultList(); 
} 

サンプルログここで

は、コードサンプルです最初の2つのログは正しいです...ユーザーがプリファレンスを変更すると(SessionBeanが更新されます)、ビューはJSFで再レンダリングされ、最後の2つのログが正しい順序でなくなり、アプリケーションが混乱します。

ありがとうございました。

答えて

2

@PostConstructは、起動アクションフェーズでは実行されません。 Beanの構築の直後に実行されます。 PostConstructは、Beanの構築の直後に注入された依存関係に依存して、いくつかのものを初期化するためにのみ使用してください。 Beanは対話スコープ(またはビュースコープ)ではなくリクエストスコープであるため、リクエストごとに作成されます。

<h:commandButton>/<h:commandLink>で指定した方法ではなく、実際の処理方法で更新/更新ジョブを実行する必要があります。例えば。

public void submit() { 
    // ... 

    retrieveAllSubAccount(); 
} 

<h:commandButton value="Submit" action="#{bean.submit}" /> 

私もそれが不必要に同じビューにすべてのポストバックに再構築されないように、CDIの対話スコープやJSFビューのスコープ内にBeanを置くことをお勧めします。

+0

ありがとうございます。私はそれを推測し、そのメソッドから@PostConstructを削除し、迅速な回避策としてビューのゲッターから呼び出します。これは今動作します。実際には私はこれをmavenのアーキタイプで手に入れました。そして、これは推奨されていないことをjbossから伝えます。 – SpecialAgent

+0

いいえ、 '@ PostConstruct'はそこに問題ありません。あなたは、それが使われるべきものを誤解しているだけです。それは、豆の建設の直後に物を事前に初期化することです。リクエストスコープのBeanは、すべてのHTTPリクエストで構築されます。これはすべて仕様によるものです。フォームの送信アクション(たとえば、編集したアイテムを保存し、表示するためにリストを再ロードするなど)を呼び出すには、指定されたアクションメソッドでジョブを実行する必要があります。 – BalusC

関連する問題