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
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:
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());
}
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();
}
};
Make LazyUserDataModel
a managed bean as well and inject it instead.
@Named @RequestScoped
public class LazyUserDataModel extends LazyDataModel<User> {
// ...
}
with
@Inject
private LazyUserDataModel lazyUsers;
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With