Reputation: 1675
Class 1: Repository.java:
@ApplicationScoped
public class Repository {
@Inject
private EntityManager em;
public Term findById(Long id) {
return em.find(Term.class, id);
}
}
Class 2: Word.java
@Named
@RequestScoped
public class Word {
@Inject
private Logger log;
@Inject
private Repository repository;
private Term term;
public Word() {
}
public Word(Long id) {
try{
term = this.findTermById(id);
}catch(Exception e) {
e.printStackTrace();
}
}
@Produces
@Named
public Term getTerm() {
return term;
}
public Term findTermById(Long id) {
Term term = repository.findById(id);
if(term==null) {
log.info("Can't find this word from database: " + term);
}
return term;
}
}
Class 3: Resources.java
public class Resources {
@Produces
@PersistenceContext
private EntityManager em;
@Produces
public Logger produceLog(InjectionPoint injectionPoint) {
return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
}
@Produces
@RequestScoped
public FacesContext produceFacesContext() {
return FacesContext.getCurrentInstance();
}
}
The problem with these two classes is that, when running the server, it throws an NullPointerException at the line:
Term term = repository.findById(id);
which means the injection of the object 'repository' failed, since debugging shows that "repository=null".
@Inject
private Repository repository;
Why does the injection is unsuccessful? Thank you.
Upvotes: 0
Views: 2782
Reputation: 1479
As @Geinmachi said, you are calling it in the constructor but you are not injecting it in the constructor but on field level which is not initialized until @PostConstruct.
You can use constructor injection to inject the repository as a parameter but instead you should not be manually instantiating Word but through CDI injection as well.
@Inject
public Word(Repository repo) {
this.repo = repo;
}
In general a constructors should never be doing actions (like the db lookup you are doing), it is very bad practice because no one knows the behavior from outside plus you won't have a transaction going during @Inject. Also you should not manually instantiate CDI beans because their lifecycle is managed by CDI and are designed to be used through @Inject.
Also you will have concurrency issues by having an Applicationscoped entitymanager, it should be requestscoped.
Upvotes: 1
Reputation: 186
Don't you have full stacktrace? I think the NullPointerException might come from private EntityManager em;
being null in your Repository bean.
CDI doesn't see your class Resources, as it is not defined bean. (As far as I can tell from the code.)
Upvotes: 0