I am developing some application, which consists of three layers:
- Database access layer (JPA + Hibernate as provider)
- Business logic layer
- Presentation layer (JSF 2.0)
Before I started I have read some chapters from the book Core JavaServer Faces (3rd Edition) by David Geary and Cay S. Horstmann. In this book, authors strongly recommend using @Named
annotation instead of @ManagedBean
. Ok, I thought I can try.
Then I proceeded to layers construction of my application by just implementing some basic functionality - users logging in.
I also read about some new annotation, namely @Inject
. I thought that it can be very comfortable to just inject one layer into another basing only on interfaces. But I am afraid that I misunderstood something, so I came to you with my problem.
Let me present 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";
}
// getters and setters
}
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) {
// some logic
}
}
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) {
// some data processing
}
}
This last class operates on some Java class with @Entity
annotation, nevermind.
I have a feeling that something is wrong with my solution.
Basic bug is fact, that even if I provide some data to the form created with <h:form>
, <h:inputText>
tag, when debugging verify()
method I can see, that login
and password
are null
, so something is wrong here, but I have no idea what.
I have also concerns if I understand @Inject
well. Can I use it in such way like provided above to couple layers using interfaces?
Ok. I found reason why I get nulls on login and password fields, but I don't know the solution yet. It happens because during execution in some magic way, there are multiple (at least two) instances of CredentialsBean created. Checked in Eclipse debugger. First gets its fields set properly, but second one does not, and this second one's values are sent to service layer. I am wondering if it is not a question of scope. Shouldn't I put @SessionScoped in CredentialsBean?