我认为这个问题引发了,因为我没有得到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?
由于
答案 0 :(得分:16)
EJB仅在托管bean中注入。当bean由一些注入容器管理时,例如通过JSF自己的@ManagedBean
,CDI的@Named
等来管理bean。您甚至可以在另一个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;
像你想象的那样创建一个完整的匿名实例。
无关,没有必要提供LazyDataModel
,您提供所有记录。它的目的是让您可以根据当前的分页状态仅使用SQL权限(LIMIT
,OFFSET
和朋友)请求一个子集或记录,这样您就不需要数百个如果不是Java内存中的数千个记录,但只有十个左右。换句话说,如果您从未使用first
方法的pageSize
和/或load()
参数,那么您很可能完全错误地接近它。
答案 1 :(得分:4)
您只能在容器创建的bean和EJB中注入bean和EJB。不在您使用new
自我实例化的对象内部。容器不知道您实例化的对象,因此无法在这些对象中注入任何内容。
因此,只需让容器实例化并注入LazyUserDataModel对象:
@Named
@SessionScoped
public class UserPM {
@Inject
private LazyUserDataModel lazyUsers;
...
}