19

2 種類のリポジトリを管理する次のコードがあります。どちらのリポジトリ クラスも、リソースの再初期化を可能にするインターフェイスを継承します。

public interface CachingRepository
{
    public void invalidateCache();
}

グローバルなアプリケーション スコープのリポジトリ:

@Named("globalRepo")
@ApplicationScoped
public class GlobalRepository implements CachingRepository
{
    private List<Category> categories;

    ...

    @Override
    public void invalidateCache()
    {
        categories = null;
    }

    ...
}

ユーザーごとのセッション スコープのリポジトリ:

@Named("userRepo")
@SessionScoped
//@Stateful         // <- NOTE HERE
public class UserRepository implements CachingRepository, Serializable
{
    private List<MyFile> files;

    @Override
    public void invalidateCache()
    {
        files = null;
    }

    ...
}

これを(なしで@Stateful)コンテキストに注入すると

@Named
@ViewScoped
public class MyHandler implements Serializable
{
    @Inject
    private UserRepository userRepo;

    ...
}

できます。ただし、クラスに追加@StatefulするとUserRepository、デプロイは失敗し、次の例外が発生します。

Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [UserRepository] with qualifiers [@Default] at injection point [[field] @Inject private de.company.project.pack.MyHandler.userRepo]
    at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:275)
    at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:244)
    at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:107)
    at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:127)
    at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:346)
    at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:331)
    at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:366)
    at org.jboss.as.weld.WeldContainer.start(WeldContainer.java:83)
    at org.jboss.as.weld.services.WeldService.start(WeldService.java:76)
    ... 5 more

次のようにCDI Beanの名前を追加します

@Inject @Named("userRepo")
private UserRepository userRepo;

同じ例外が発生します。と組み合わせて機能する唯一のこと@Statefulは、var 宣言でインターフェイスを使用することです。

@Inject @Named("userRepo")
private CachingRepository userRepo;

ただし、ここではサブクラス機能が必要になる可能性があるため、CachingRepository(現時点では) 使用することはあまり望ましくありません。

Q :

  1. これが期待どおりに機能しないのはなぜですか? var は、UserRepositoryインスタンス化するクラスをすでに識別しているはずですよね? これの論理は何ですか?
  2. @StatefulEJB アノテーションがここまで深刻な影響を与えるのはなぜでしょうか? CachingRepository本質的に var 宣言でインターフェイスを使用する必要があるのはなぜですか?

私は Seam 3 Faces を使用して をCDI@ViewScopedビュースコープの Bean にすることに注意してください。

4

5 に答える 5

11

私はこの誤解を招く例外で同じ問題を抱えていました...

追加@Statefulすることにより、インターフェースのないビューを宣言せずに、インターフェースUserRepositoryの EJB メソッドを公開します。CachingRepositoryに追加@LocalBeanUserRepositoryて、インターフェースなしのビューを有効にします。EJB 3.1 仕様のセクション 4.9.8「セッション Bean の No-Interface ビュー」を参照してください。

Bean クラスは、その Bean クラス定義またはデプロイメント記述子を介して、インターフェースなしのビューを公開することを指定する必要があります。次の規則が適用されます。

  • ...
  • Bean が少なくとも 1 つの他のクライアント ビューを公開する場合、Bean は、Bean クラスまたはデプロイメント記述子で @LocalBean アノテーションを使用して、インターフェースのないビューを公開することを指定します。
  • ...

インターフェイスのないビューの詳細については、このスタックオーバーフローの回答も参照してください。

于 2012-04-30T19:23:32.360 に答える
2

同じエラーが発生しました。

原因: org.jboss.weld.exceptions.DeploymentException: WELD-001408: インジェクション ポイント [BackedAnnotatedField] @Inject で修飾子 @Default を持つタイプ UserTransaction の満たされていない依存関係

この問題を次のように解決しました。エラーを受け取ったときに、このように UserTransaction を使用しました。

@Inject
UserTransaction trans;

の代わりに、注釈@Injectを使用しました。@Resource

于 2019-08-29T06:48:03.790 に答える