I am developing an application consisting of three layers:
- Database Access Level (JPA + Hibernate as a Provider)
- Business logic level
- Presentation Level (JSF 2.0)
Before I started, I read a few chapters from Core JavaServer Faces (3rd Edition) by David Geary and Kay S. Horstmann. In this book, authors strongly recommend using @Named
annotation instead of @ManagedBean
. Ok, I thought I could try.
Then I proceeded to create the layers of my application, simply by performing some basic functions - users are logged in.
I also read about a new annotation, namely @Inject
. I thought it was very convenient to just paste one layer into another, based only on interfaces. But I'm afraid that I did not understand something, so I came to you with my problem.
Let me introduce some parts of my code:
CredentialsBean.java
@Named("userCredentials") public class CredentialsBean { @Inject AccountService accountService; private String login; private String password; public String verify() { if (accountService.verifyCredentials(login, password)) return "success"; else return "failure"; }
AccountService.java
public interface AccountService { public Boolean verifyCredentials(String login, String password); }
AccountServiceImpl.java:
public class AccountServiceImpl implements AccountService { @Inject AccountDAO dao; @Override public Boolean verifyCredentials(String login, String password) {
AccountDAO.java
public interface AccountDAO { public Account getAccount(String login); }
AccountDAOImpl.java
public class AccountDAOImpl implements AccountDAO { @PersistenceContext(unitName = "MyApp") protected EntityManager em; public EntityManager getEntityManager() { return em; } @Override public Account getAccount(String login) {
This last class runs on some kind of Java class with annotation @Entity
, nevermind.
I have a feeling that something is wrong with my decision.
The basic error is the fact that even if I provided some data to the form created with the <h:form>
, <h:inputText>
, when debugging the verify()
method, I can see that login
and password
are null
>, so here what something is wrong, but I have no idea what.
I also have problems if I understand @Inject
well. Can I use it this way, as shown above, to interface layers using interfaces?
Ok I found the reason why I get nulls in the login and password fields, but I don't know the solution yet. This is because at run time in some magical way there are several (at least two) instances of CredentialsBean. Checked in the Eclipse debugger. First, its fields are set correctly, and the second is not, and this second value is sent to the service level. I wonder, not a question of volume. Should I put @SessionScoped in a CredentialsBean?