1

(これは基本的にこの質問のフォローです。)

フォーム バリデーターの 1 つで DB サービス レイヤーにアクセスする必要があります (新しいユーザーを登録するときにメールがまだ取得されていないことを確認するため)。

私は次のことを試しました(簡潔にするためにいくつかの入力フィールドを省略しました):

public class RegistrationPage extends WebPage {

    @Inject
    private UserService userService;

    public RegistrationPage() {

        add(new FeedbackPanel("feedback"));

        TextField<String> email = new TextField<String>("email", Model.of(""));

        ...

        email.add(new IValidator<String>() {

            @Override
            public void validate(IValidatable<String> validatable) {

                String email = validatable.getValue();

                if (userService.findUserByEmail(email) != null) {

                    // report error...

                }
            }
        });

        Form<?> form = new Form<Void>("registrationForm") { ... };

        form.add(email);
        add(form);
    }
}

これにより、残念ながら

java.lang.IllegalStateException: EntityManager is closed

この問題は、open-session-in-view を使用していて、複数のフォーム送信が複数のリクエストにまたがっていることが原因であると思われます。はuserService最初のリクエストで注入され、その後のリクエストで (違法に) 再利用されます。(検証が失敗し、ユーザーがフォームを再度送信しようとすると、複数のフォーム送信が発生します。)

私の質問

これを解決する最善の方法は何ですか? 以前の同様の問題を解決したのと同じ方法ですか?この場合、間違いなく混乱します。

4

1 に答える 1

0

あなたが望むライフサイクルとウィケットが使用するライフサイクルは少し異なります。

まず最初に考え、Wicket コンポーネントのインスタンス化とインジェクションを理解します。

  1. コンポーネントをインスタンス化する
  2. インジェクタを呼び出す - IComponentInstationListener.onInstantiation(Component component)
  3. 注釈付きフィールドを挿入
  4. コンポーネントを使用する(レンダリングなど)
  5. 次のリクエスト - フィールドが挿入された同じコンポーネントを使用する

何をすべきか?フィールドに注入されるプロキシ クラスを使用します。プロキシ クラスが呼び出されると、現在の Bean が使用されます。

http://ci.apache.org/projects/wicket/apidocs/6.0.x/org/apache/wicket/spring/injection/annot/SpringComponentInjector.htmlの SprinComponentInejctor を参照してください。

http://ci.apache.org/projects/wicket/apidocs/6.0.x/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.htmlの AnnotProxyFieldValueFactory を参照してください。

独自の実装を作成するか、Wicket Contrib または Wicket Stuff を参照する必要があります。

于 2013-06-25T16:00:57.667 に答える