Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NullPointerException when injecting EJB in Java Class

Tags:

java

jsf

ejb

I think this problem raises because I didn't get something with EJBs. I have a service class for my entity, which is @Stateless. When I use it by injecting with @EJB in my session scoped presentation model, all is ok. But now I wanted to use this EJB service in a DataModel I have overwritten for use in my presentation model:

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; 
    }
}

On execution I get a NullPointerException at position "users= service.findAllUsers();" The same works, when I overwrite this DataModel in my presentation model:

@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 ; 
                }
        };
    }
}

Isn't it possible to Inject an EJB in a normal Java Class? What must I do that I don't have to define the DataModel in the presentation model?

Thanks

like image 451
timmornYE Avatar asked Aug 02 '13 12:08

timmornYE


Video Answer


1 Answers

EJBs are only injected in managed beans. A bean is managed when it's managed by some injection container, such as via JSF's own @ManagedBean, CDI's @Named, etc. You can even inject an EJB in another EJB. You cannot inject an EJB in an unmanaged class (you can however manually grab it from JNDI, but that's plain ugly).

You've basically the following options:

  1. In @PostConstruct of your managed bean, construct the datamodel whereby you pass the result as argument (note that this is also how standard data models like ListDataModel work).

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

  2. Make LazyUserDataModel abstract whereby you ask the user to provide the result.

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

    so that the anonymous class hurts less

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

  3. Make LazyUserDataModel a managed bean as well and inject it instead.

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

    with

    @Inject
    private LazyUserDataModel lazyUsers;
    

  4. Create a fullfledged anonymous instance like as you figured.


Unrelated to the concrete problem, there's no point of having a LazyDataModel whereby you provide all records. Its intent is that it offers you the possibility to request only a subset or records using SQL powers (LIMIT, OFFSET and friends) based on the current paginated state so that you don't need to have hundreds if not thousands records in Java's memory but only ten or so. In other words, if you are never using first and/or pageSize argument of the load() method, you're most likely approaching it completely wrong.

like image 68
BalusC Avatar answered Sep 28 '22 06:09

BalusC