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!