在Java类中注入EJB时出现NullPointerException

我认为这个问题引发了,因为我没有得到EJB的东西。 我有一个我的实体的服务类,它是@Stateless。 当我通过在我的会话范围演示模型中注入@EJB来使用它时,一切正常。 但是现在我想在我已覆盖的DataModel中使用这个EJB服务,以便在我的演示模型中使用:

public class LazyUserDataModel extends LazyDataModel { @EJB private UserService service; @Override public List load(int first, int pageSize, String sortField, SortOrder sortOrder, Map filters) { List 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 lazyUsers; public UserPM() { // Don't works //lazyUsers = new LazyUserDataModel(); lazyUsers = new LazyDataModel() { @Override public List load(int first, int pageSize, String sortField, SortOrder sortOrder, Map filters) { List users; users = service.findAllUsers(); this.setRowCount(users .size()); return users ; } }; } } 

是不是可以在普通的Java类中注入EJB? 我必须做什么,我不必在演示模型中定义DataModel?

谢谢

EJB仅在托管bean中注入。 当bean由一些注入容器管理时,例如通过JSF自己的@ @ManagedBean ,CDI的@Named等,管理bean。您甚至可以在另一个EJB中注入EJB。 您不能在非托管类中注入EJB(但是您可以从JNDI手动获取它,但这很简单)。

你基本上有以下选择:

  1. 在托管bean的@PostConstruct中,构造数据模型,从而将结果作为参数传递(请注意,这也是ListDataModel等标准数据模型的工作方式)。

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

  2. 使LazyUserDataModel抽象,您要求用户提供结果。

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

    这样匿名课就会受到伤害

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

  3. 使LazyUserDataModel成为托管bean,然后将其注入。

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

     @Inject private LazyUserDataModel lazyUsers; 

  4. 像你想象的那样创建一个完整的匿名实例。


具体问题无关 ,没有必要使用LazyDataModel来提供所有记录。 它的目的是它使您可以根据当前的分页状态仅使用SQL权限( LIMITOFFSET和朋友)请求一个子集或记录,这样您就不需要在Java的内存中拥有数百条(如果不是数千条)记录,只有十个左右。 换句话说,如果你从不使用load()方法的first和/或pageSize参数,那么你很可能完全错误地接近它。

您只能在容器创建的bean和EJB中注入bean和EJB。 不在使用new实例化自己的对象内部。 容器不知道您实例化的对象,因此无法在这些对象中注入任何内容。

因此,只需让容器实例化并注入LazyUserDataModel对象:

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