我认为出现这个问题是因为我对 EJB 没有了解。我的实体有一个服务类,它是@Stateless。当我通过在 session 范围的表示模型中注入(inject) @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 类中注入(inject) EJB 吗?我必须做什么才能不必在表示模型中定义数据模型?
谢谢
最佳答案
EJB 仅注入(inject)托管 bean。当一个 bean 被一些注入(inject)容器管理时,它被管理,例如通过 JSF 自己的 @ManagedBean
,CDI 的 @Named
等。您甚至可以在另一个 EJB 中注入(inject)一个 EJB。您不能在非托管类中注入(inject) 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 并将其注入(inject)。@Named @RequestScoped public class LazyUserDataModel extends LazyDataModel<User> { // ... }
与
@Inject private LazyUserDataModel lazyUsers;
像您想象的那样创建一个完整的匿名实例。
与具体问题无关,没有必要通过 LazyDataModel
提供所有 记录。它的目的是让您可以根据当前分页状态使用 SQL 功能(LIMIT
、OFFSET
和 friend )仅请求一个子集或记录,这样您就不必不需要在 Java 内存中有成百上千条记录,但只需要十条左右。换句话说,如果您从不使用 load()
方法的 first
和/或 pageSize
参数,您很可能正在接近它完全错误。
关于java - 在 Java 类中注入(inject) EJB 时出现 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18017008/