I am building a web application with NetBeans 8.0.2 using JSF (2.2) and EclipseLink (JPA 2.1).
Let's assume that the current functionality is quiet basic inlcuding: login, logout, register, user roles, pages available only to admins (by using filters) etc.
I have read maaany SO Q&A (mostly from @BalusC, thanks!) and would like to verify that my design is correct/follows best practices.
Currently I have:
A user Entity (UserEntity.java)
Maybe this name is redundant, but I wanted an obvious name to begin with), corresponding to the user in database:
@Entity
@Table(name = "Users")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "UserEntity.findAll", query = "SELECT u FROM UserEntity u")...})
public class UserEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "userID")
private Integer userID;
...
}
A user bean (User.java)
It uses the UserService and keeps a relevant UserEntity. Its methods are used in the EL of the .xhtml files
@ManagedBean(name = "user") // name not needed here, but I kind of like it
@SessionScoped
public class User implements Serializable {
private UserEntity userEntity; // with getter or make this public to be accessed directly from EL?
public String login() {
userEntity = UserService.find(username);
...
}
...
}
And a UserService.java
which basically has the database access methods:
public class UserService {
public static String insertUser(UserEntity user) {
String retMessage;
EntityManager em = JPAResource.factory.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
em.persist(user);
tx.commit();
retMessage = "ok";
return retMessage;
}
catch (PersistenceException e) {
if (tx.isActive()) tx.rollback();
retMessage = e.getMessage();
return retMessage;
}
finally {
em.close();
}
}
...
}
At some point I noticed that the UserService could have only static methods, so I can access them without creating instances.
Is that bad and why?
I guess the correct way would be to have the UserService as: import javax.ejb.TransactionAttribute; import javax.ejb.TransactionAttributeType; ...
@Stateless
public class UserService {
@PersistenceContext
private EntityManager em;
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public static String insertUser(UserEntity user)
{
em.persist(user);
}
...
}
and the user bean as:
@ManagedBean(name = "user")
@SessionScoped
public class User implements Serializable {
@EJB
private UserEntity userEntity;
public String login() {
userEntity = UserService.find(username);
...
}
...
}
Is that correct?
I am not sure what exactly the @Stateless, @EJB, PersistenceContext do/mean.
(Are they from javax.ejb.Stateless, javax.ejb.EJB, javax.persistence.PersistenceContext respectively?)
Does using @Stateless and @EJB allow me to utilize my UserService without creating instances of it and without having static methods?
What about checking the transactions? Does @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) have me covered? i.e. no need for further checks? If an exception is thrown, will the method return with the relevant message?
With @PersistenceContext, what/who is creating the EntityManager instance?
Is this design good practice, respecting the separation of concerns etc?
Thanks!