在Java类中注入EJB时出现NullPointerException

在Java类中注入EJB时出现NullPointerException,java,jsf,ejb,Java,Jsf,Ejb,我认为这个问题的出现是因为我没有从EJB中得到一些东西。我的实体有一个服务类,它是@Stateless。当我通过在会话范围的表示模型中注入@EJB来使用它时,一切都正常。但是现在我想在一个数据模型中使用这个EJB服务,我已经覆盖了这个数据模型,以便在我的表示模型中使用: public class LazyUserDataModel extends LazyDataModel<User> { @EJB private UserService service;

我认为这个问题的出现是因为我没有从EJB中得到一些东西。我的实体有一个服务类,它是@Stateless。当我通过在会话范围的表示模型中注入@EJB来使用它时,一切都正常。但是现在我想在一个数据模型中使用这个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; 
    }
}
公共类LazyUserDataModel扩展了LazyDataModel{
@EJB
私人用户服务;
@凌驾
公共列表加载(int-first、int-pageSize、字符串排序字段、排序器排序器、映射过滤器){
列出用户名单;
users=service.findAllUsers();
this.setRowCount(users.size());
返回用户;
}
}
执行时,我在位置“users=service.findAllUsers();”处得到一个NullPointerException,当我在演示模型中覆盖此数据模型时,同样有效:

@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 ; 
                }
        };
    }
}
@Named
@会议范围
公共类UserPM{
@EJB
私人用户服务;
私人懒散数据模型懒散用户;
公共用户pm(){
//不行
//lazyUsers=新的LazyUserDataModel();
lazyUsers=新的LazyDataModel(){
@凌驾
公共列表加载(int-first、int-pageSize、字符串排序字段、排序器排序器、映射过滤器){
列出用户名单;
users=service.findAllUsers();
this.setRowCount(users.size());
返回用户;
}
};
}
}
难道不可能在普通Java类中注入EJB吗?我必须做什么才能不必在表示模型中定义数据模型


谢谢

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

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

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

    ...
}

EJB只注入托管bean中。当bean由某个注入容器管理时,就会对其进行管理,例如通过JSF自己的
@ManagedBean
、CDI的
@Named
,等等。您甚至可以在另一个EJB中注入EJB。您不能在非托管类中注入EJB(但是您可以从JNDI手动获取它,但这很难看)

您基本上有以下选项:

  • 在托管bean的
    @PostConstruct
    中,构造数据模型,通过该模型将结果作为参数传递(注意,这也是标准数据模型的工作方式)


  • 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();
    
    }
    


  • 创建一个完整的匿名实例,如图所示



  • 与具体问题无关,没有必要使用
    LazyDataModel
    来提供所有记录。它的目的是让您可以根据当前分页状态,使用SQL powers(
    LIMIT
    OFFSET
    和friends)仅请求一个子集或记录,这样您就不需要在Java内存中有成百上千条记录,而只需要十条左右。换句话说,如果您从未使用
    load()
    方法的
    first
    和/或
    pageSize
    参数,则很可能是完全错误的方法。

    尝试将BeanInterface放入EJB注释中。我以前也有同样的问题,这就解决了
    @EJB(beanInterface=YourInterface.class)
    感谢@BalusC给出的详细答案。在我尝试这一点之前,先谈谈两个话题:我知道懒散的数据模型在这种情况下是没有意义的。我只想尽量简化代码。但我真正不理解的是您的第一条语句:在哪个构造函数中,服务应该为null?在“public UserPM()”中?如果我没有忽略某些东西,那么这正是它对我的作用。注入的依赖项在Constructor中不可用,但最早只在
    @PostConstruct
    中可用,原因很简单,因为在构造实例之前无法设置实例变量。这很奇怪。正如你所说,我记得这一点。但它就是这样运作的。也许是因为凌驾而有所不同?对不起,我错了。您在一个匿名方法中引用它,当然在构造时不会调用该方法。但至少,这不是一种好的编码风格。将后构造逻辑放入
    @postconstruct
    方法中。保持构造函数为空。最好是,托管/企业bean不应该有任何显式构造函数。你知道为什么吗?
    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();
        }
    };
    
    @Named @RequestScoped
    public class LazyUserDataModel extends LazyDataModel<User> {
        // ...
    }
    
    @Inject
    private LazyUserDataModel lazyUsers;