15

EJB で何も得られなかったために、この問題が発生したと思います。@Stateless というエンティティのサービス クラスがあります。セッションスコープのプレゼンテーションモデルで @EJB を注入して使用すると、すべて問題ありません。しかし、プレゼンテーション モデルで使用するために上書きした DataModel で、この EJB サービスを使用したいと思いました。

public class LazyUserDataModel extends LazyDataModel<User> {

    @EJB
    private UserService service;

    @Override
    public List<User> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map filters) {
        List<User> users;
        users= service.findAllUsers();
        this.setRowCount(users.size());
        return users; 
    }
}

実行時に、「users=service.findAllUsers();」の位置で NullPointerException を取得します。プレゼンテーション モデルでこの DataModel を上書きすると、同じことが機能します。

@Named
@SessionScoped
public class UserPM {
    @EJB
    private UserService service;

    private LazyDataModel<User> lazyUsers;

    public UserPM() {

            // Don't works
            //lazyUsers = new LazyUserDataModel();

            lazyUsers = new LazyDataModel() {
            @Override
                public List<User> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map filters) {
                    List<User> users;
                    users = service.findAllUsers();
                    this.setRowCount(users .size());
                    return users ; 
                }
        };
    }
}

通常の Java クラスに EJB を注入することはできませんか? プレゼンテーション モデルで DataModel を定義する必要がないようにするにはどうすればよいですか?

ありがとう

4

2 に答える 2

18

EJB はマネージド Bean にのみ注入されます。@ManagedBeanBean は、JSF 独自の、CDIなどを介した注入コンテナによって管理される場合に管理され@Namedます。EJB を別の EJB に注入することもできます。アンマネージ クラスに EJB を注入することはできません (ただし、JNDI から手動で取得することはできますが、それは明らかに見苦しいものです)。

基本的に次のオプションがあります。

  1. @PostConstructマネージド Bean で、結果を引数として渡すデータモデルを構築します (これは、標準的なデータ モデルのような動作でもあることに注意してください) ListDataModel

    @PostConstruct
    public void init() {
        lazyUsers = new LazyUserDataModel(service.findAllUsers());
    }
    

  2. LazyUserDataModelユーザーに結果を提供するように求める抽象化を行います。

    public abstract class LazyUserDataModel extends LazyDataModel<User> {
    
        @Override
        public List<User> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map filters) {
            List<User> users;
            users = findAllUsers();
            this.setRowCount(users.size());
            return users ; 
        }
    
        public abstract List<User> findAllUsers();
    
    }
    

    匿名クラスの害が少なくなるように

    lazyUsers = new LazyUserDataModel() {
        @Override
        public List<User> findAllUsers() {
            return service.findAllUsers();
        }
    };
    

  3. マネージドLazyUserDataModelBean も作成し、代わりに注入します。

    @Named @RequestScoped
    public class LazyUserDataModel extends LazyDataModel<User> {
        // ...
    }
    

    @Inject
    private LazyUserDataModel lazyUsers;
    

  4. あなたが考えたように、本格的な匿名インスタンスを作成します。


具体的な問題とは関係ありませんが、すべての記録LazyDataModelを提供しても意味がありません。その意図は、現在のページ分割された状態に基づいて、SQL パワー ( 、およびその仲間) を使用してサブセットまたはレコードのみを要求する可能性を提供することです。これにより、Java のメモリに数千ではないにしても数百のレコードが必要ではなく、10 のみのレコードが必要になります。とか、ぐらい。つまり、メソッドのand/or引数をまったく使用していない場合は、完全に間違った方法でアプローチしている可能性が高くなります。LIMITOFFSETfirstpageSizeload()

于 2013-08-02T12:46:31.497 に答える
4

コンテナーによって作成された Bean および EJB 内にのみ、Bean および EJB を注入できます。を使用して自分でインスタンス化するオブジェクト内ではありませんnew。コンテナは、インスタンス化したオブジェクトを認識しないため、これらのオブジェクトに何も注入できません。

したがって、コンテナーをインスタンス化し、LazyUserDataModel オブジェクトを注入するだけです。

@Named
@SessionScoped
public class UserPM {
    @Inject
    private LazyUserDataModel lazyUsers;

    ...
}
于 2013-08-02T12:45:54.693 に答える