0

アプリで奇妙な動作をします。SessionScopeBean(Bean A)を使用してユーザー設定を保持します。RequestScopeにある他のBean(Bean B)で、SessionScopeBeanを注入します。

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

すべてのセッターメソッドは、アプリケーションフェーズの呼び出しの前に更新されると思いますか?

コードサンプルは次のとおりです。

Bean 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;
}

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

サンプルログ:

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]

ご覧のとおり...最初の2つのログは正しいです...ユーザーが設定を変更した場合(SessionBeanを更新した場合)、ビューはJSFで再レンダリングされ、最後の2つのログは正しい順序ではなく、アプリが混乱します。

助けてくれてありがとう。

4

1 に答える 1

2

@PostConstruct呼び出しアクションフェーズでは実行されません。Beanの構築直後に実行されます。はPostConstruct、Beanの構築直後に注入された依存関係に応じて、一部のものを事前初期化するためにのみ使用する必要があります。Beanは会話スコープ(またはビュースコープ)ではなくリクエストスコープであるため、すべてのリクエストで作成されます。

<h:commandButton>代わりに、 /で指定したメソッドである実際のアクションメソッドで更新/更新ジョブを実行する必要があります<h:commandLink>。例えば

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

public void submit() {
    // ...

    retrieveAllSubAccount();
}

また、同じビューへのポストバックごとにBeanが不必要に再構築されないように、BeanをCDI会話スコープまたはJSFビュースコープに配置することをお勧めします。

于 2012-01-06T13:22:09.223 に答える