私は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を定義する必要がないようにするにはどうすればよいですか?
ありがとう
EJBは、マネージドBeanにのみ注入されます。 Beanは、JSF独自の_@ManagedBean
_、CDIの_@Named
_などを介して、何らかのインジェクションコンテナによって管理されている場合に管理されます。別のEJBにEJBをインジェクトすることもできます。アンマネージクラスにEJBを挿入することはできません(ただし、JNDIから手動で取得することはできますが、それは明らかに醜いです)。
基本的に次のオプションがあります。
管理対象Beanの_@PostConstruct
_で、結果を引数として渡すデータモデルを構築します(これは、 ListDataModel
のような標準データモデルの動作方法でもあることに注意してください)。
_@PostConstruct
public void init() {
lazyUsers = new LazyUserDataModel(service.findAllUsers());
}
_
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();
}
};
_
LazyUserDataModel
もマネージドBeanにして、代わりに注入します。
_@Named @RequestScoped
public class LazyUserDataModel extends LazyDataModel<User> {
// ...
}
_
と
_@Inject
private LazyUserDataModel lazyUsers;
_
あなたが考えたように、本格的な匿名インスタンスを作成します。
具体的な問題とは無関係、allレコードを提供するLazyDataModel
を持つ意味はありません。その目的は、現在のページ付けされた状態に基づいて、SQLパワー(LIMIT
、OFFSET
およびその仲間)を使用してサブセットまたはレコードのみを要求する可能性を提供することです。 Javaのメモリには、数千とは言わないまでも数百のレコードがありますが、10程度しかありません。つまり、load()
メソッドのfirst
および/またはpageSize
引数を使用したことがない場合は、完全に間違ったアプローチをしている可能性があります。
コンテナによって作成されたBeanおよびEJB内にのみBeanおよびEJBを挿入できます。 new
を使用して自分でインスタンス化するオブジェクトの内部ではありません。コンテナは、インスタンス化するオブジェクトを認識しないため、これらのオブジェクトに何も注入できません。
したがって、コンテナをインスタンス化してLazyUserDataModelオブジェクトを挿入するだけです。
@Named
@SessionScoped
public class UserPM {
@Inject
private LazyUserDataModel lazyUsers;
...
}