JSF #managedproperty and #PostConstruct - jsf

I have a problem with JSF2 #ManagedProperty annotation. I have a managed bean that create a user, then i want to pass this user to another bean to display other informations relative to that user. So my code is below :
#Named("userController")
#SessionScoped
public class UserController implements Serializable {
#EJB
private session.UserFacade ejbFacade;
private List<User> items = null;
private User selected;
private User utente;
private String user;
private String pass;
----getter and setter----
In the Schedule Bean I use the userController bean in the #PostConstruct :
#Named(value = "scheduleController")
#SessionScoped
public class ScheduleController implements Serializable {
private ScheduleModel eventModel;
private ScheduleEvent event = new DefaultScheduleEvent();
#EJB
ActivityFacade ejbFacade;
#ManagedProperty(value="#{userController}")
private UserController credentials;
public ScheduleController() {
}
#PostConstruct
public void init(){
eventModel = new DefaultScheduleModel();
List<Activity> daFare =ejbFacade.findForUser(credentials.getUtente().getIdUser());
for(int i=0;i<daFare.size();i++){
eventModel.addEvent(new DefaultScheduleEvent(daFare.get(i).getDescrizione(),daFare.get(i).getDalleOre(),daFare.get(i).getAlleOre() ));
}
}
public void setCredentials(UserController credentials) {
this.credentials = credentials;
}
When i debug the code, I see that the UserController credentials is always null.... What's wrong ? I need to specify something in faces-config.xml ?
Thanks a lot for your tips.
EDIT :
After change #ManagedProperty with #Inject and after add the below beans.xml in WEB-INF folder, the problem persist.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
The app work in this way:
A user can log in via this xhtml page:
<body>
<h:form>
<p:growl id="msgs" showDetail="true" />
<p:panel header="Inserisci i tuoi dati" style="margin: 0 auto; text-align: center" >
<h:panelGrid columns="2" cellpadding="5" style="margin: 0 auto; text-align: center">
<p:outputLabel value="Username"/>
<p:inputText value="#{userController.user}" required="true" label="Username" size="40"/>
<p:outputLabel value="Password" />
<p:password value="#{userController.pass}" required="true" label="Password" size="40"/>
<p:commandButton action="#{userController.validateLogin}" value="Login" update="msgs" ajax="false" style="text-align: center"/>
</h:panelGrid>
</p:panel>
</h:form>
</body>
After submit the form, the userController verify that this specific user exist in a DB table and then instantiate the User utente ( id, username, password, email as field ). After this, the app redirect to home.xhtml that display several user's information and select several information of a DB table selected by user's id.
Here is the code where I set User utente:
public String validateLogin(){
String output="home";
boolean exist=false;
exist=ejbFacade.logValid(user,pass);
if(!exist){
//FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Username o Password errata","Contattare l'amministratore"));
return "index";
}else{
utente=ejbFacade.setUtente(user);
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage("Accesso eseguito con successo.","Bentornato " + user));
return output;
}
}
The code sequence in which i control the existece of a user and set the utente is:
#Stateless
public class UserFacade extends AbstractFacade<User> {
#PersistenceContext(unitName = "ImmobiliareWebPU")
private EntityManager em;
#Override
protected EntityManager getEntityManager() {
return em;
}
public UserFacade() {
super(User.class);
}
public boolean logValid(String user, String pass) {
List<User> utente ;
boolean autorizzato;
String find = "User.findByUsername&Password";
Query query = em.createNamedQuery(find, User.class);
query.setParameter("username", user);
query.setParameter("password", pass);
utente =query.getResultList();
if (utente.isEmpty()) {
autorizzato=false;
}
else{
autorizzato=true;
}
return autorizzato;
}
public User setUtente(String user) {
//SETTO L'UTENTE PER LA SESSIONE DEL PROGRAMMA
User utente;
String find = "User.findByUsername";
Query query = em.createNamedQuery(find, User.class);
query.setParameter("username", user);
utente =(User) query.getSingleResult();
return utente;
}
}
the code where I need user's information is :
#Named(value = "scheduleController")
#RequestScoped
public class ScheduleController implements Serializable {
private ScheduleModel eventModel;
private ScheduleEvent event = new DefaultScheduleEvent();
#EJB
ActivityFacade ejbFacade;
#Inject
private UserController credentials;
public ScheduleController() {
}
#PostConstruct
public void init(){
eventModel = new DefaultScheduleModel();
List<Activity> daFare =ejbFacade.findForUser(credentials.getUtente().getIdUser());
for(int i=0;i<daFare.size();i++){
eventModel.addEvent(new DefaultScheduleEvent(daFare.get(i).getDescrizione(),daFare.get(i).getDalleOre(),daFare.get(i).getAlleOre() ));
}
}
In the ejbFacade i make a simple query :
#Stateless
public class ActivityFacade extends AbstractFacade<Activity> {
#PersistenceContext(unitName = "ImmobiliareWebPU")
private EntityManager em;
#Override
protected EntityManager getEntityManager() {
return em;
}
public ActivityFacade() {
super(Activity.class);
}
public List<Activity> findForUser(int utenteId) {
//RICHIEDO LE ATTIVITA' DEL SINGOLO UTENTE
List<Activity> daFare ;
String find = "Activity.findByUserId";
Query query = em.createNamedQuery(find, Activity.class);
query.setParameter("idUser", utenteId);
daFare =query.getResultList();
return daFare;
}
}
In debug mode i see an istance of UserController with all null fields; it seems to be a new istance of UserController. I use also "import javax.enterprise.context.SessionScoped" . Where is my fault ?

When i debug the code, I see that the UserController credentials is
always null.... What's wrong?
Please note you are mixing up CDI (Context and Dependency Injection) with Managed properties, which is probably causing the described behavior. Your beans are annotated with #Named instead of #ManagedBean so this:
#ManagedProperty(value="#{userController}")
private UserController credentials;
Should be replaced by this:
#Inject
private UserController credentials;
For a really great explanation about the difference between CDI and backing beans see #BalusC answer in this topic: Backing beans (#ManagedBean) or CDI Beans (#Named)?.
I need to specify something in faces-config.xml?
No, but you should include a beans.xml like exemplified here: Packaging CDI applications. As far as I remember this file is mandatory regardless the discovery mode. Here is the beans.xml that you can auto-generate in NetBeans:
New file --> Context and Dependency Injection --> beans.xml (CDI Configuration file).
This is all I've ever needed to make CDI work:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="annotated">
</beans>

Related

Application using Omnifaces Socket is working fine on Wildfly but wont deploy on Weblogic

I'm developing chat app using OmniFaces version 2.7 o:socket and it works like a charm when I deploy it to WildFly 13.0.0 Final but it won't deploy on WebLogic Server Version: 12.2.1.3.0.
Here is the stack trace I'm getting:
Caused By: java.lang.NullPointerException
at org.omnifaces.cdi.push.Socket.registerEndpointIfNecessary(Socket.java:976)
at org.omnifaces.ApplicationListener.contextInitialized(ApplicationListener.java:86)
at weblogic.servlet.internal.EventsManager$FireContextListenerAction.run(EventsManager.java:705)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:328)
at weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:197)
at weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:71)
at weblogic.servlet.internal.EventsManager.executeContextListener(EventsManager.java:251)
at weblogic.servlet.internal.EventsManager.notifyContextCreatedEvent(EventsManager.java:204)
at weblogic.servlet.internal.EventsManager.notifyContextCreatedEvent(EventsManager.java:189)
at weblogic.servlet.internal.WebAppServletContext.preloadResources(WebAppServletContext.java:1921)
at weblogic.servlet.internal.WebAppServletContext.start(WebAppServletContext.java:3106)
at weblogic.servlet.internal.WebAppModule.startContexts(WebAppModule.java:1843)
at weblogic.servlet.internal.WebAppModule.start(WebAppModule.java:884)
at weblogic.application.internal.ExtensibleModuleWrapper$StartStateChange.next(ExtensibleModuleWrapper.java:360)
at weblogic.application.internal.ExtensibleModuleWrapper$StartStateChange.next(ExtensibleModuleWrapper.java:356)
at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:45)
at weblogic.application.internal.ExtensibleModuleWrapper.start(ExtensibleModuleWrapper.java:138)
at weblogic.application.internal.flow.ModuleListenerInvoker.start(ModuleListenerInvoker.java:124)
I have added socket endpoint enabled to my web.xml
<context-param>
<param-name>org.omnifaces.SOCKET_ENDPOINT_ENABLED</param-name>
<param-value>true</param-value>
</context-param>
I have created minmal example that reproduces the code. Here is the source:
Here is my bean that holds all the messages:
#Data
#Named
#ApplicationScoped
public class ChatContentBean {
private List<ChatMessage> chatMessages;
#Inject
#Push
private PushContext someChannel;
#PostConstruct
public void init() {
chatMessages = new ArrayList<>();
}
public void clearHistory() {
chatMessages = new ArrayList<>();
}
public void onPageView(#Observes ChatMessage pageView) {
chatMessages.add(pageView);
someChannel.send(pageView);
}
}
My backing bean:
#Log4j
#Data
#Named
#ViewScoped
#Interceptors({ExceptionInterceptor.class})
public class ChatViewBean extends SomeOtherContentPage {
private String chatMessage;
#Inject
#Push
private PushContext someChannel;
#Inject
private BeanManager beanManager;
#Inject
private ChatContentBean chatContentBean;
#Override
#PostConstruct
public void init() {
super.init();
}
public void clearHistory() {
chatContentBean.clearHistory();
}
public void sendMessage() {
ChatMessage cm = new ChatMessage(chatMessage, AuthContext.getUser().displayName());
someChannel.send(cm);
beanManager.fireEvent(cm);
chatMessage = null;
}
}
And part of my xhtml:
<o:socket channel="someChannel" onmessage="updateStatsRc"/>
<h:panelGroup id="chat">
<ui:repeat value="#{chatContentBean.chatMessages}" var="chatElement">
<p:panelGrid columns="1">
<h:outputText value="#{chatElement.user} #{chatElement.timestamp} #{chatElement.message}"/>
</p:panelGrid>
</ui:repeat>
</h:panelGroup>
<p:remoteCommand name="updateStatsRc" update="chat"/>
<h:inputText id="chat_input_text" value="#{chatViewBean.chatMessage}"/>
<p:commandButton value="Send" update="chat_input_text" action="#{chatViewBean.sendMessage()}"/>
<p:commandButton value="Clear chat history" action="#{chatViewBean.clearHistory()}" update="chat"/>
</h:form>
And my ChatMessage class:
#Data
public class ChatMessage {
private String message;
private String timestamp;
private String user;
public ChatMessage(String message, String user) {
this.message = message;
timestamp = LocalDateTime.now().toString();
this.user = user;
}
}
I allso tryed to add org.omnifaces.ApplicationListener to web.xml but it doesnt change anything.
Any ideas why it won't deploy to weblogic but it works on wildfly?

How to create a new object instance in jsf? [duplicate]

Does it make sense to use Entities as JSF Backing Beans?
#Entity
#ManagedBean
#ViewScoped
public class User {
private String firstname;
private String lastname;
#EJB
private UserService service;
public void submit() {
service.create(this);
}
// ...
}
Or is it better to keep them separately and transfer the data from the backing bean to the entity at the end?
#ManagedBean
#ViewScoped
public class UserBean {
private String firstname;
private String lastname;
#EJB
private UserService service;
public void submit() {
User user = new User();
user.setFirstname(firstname);
user.setLastname(lastname);
service.create(user);
}
// ...
}
You could do so. It's technically possible. But it does (design)functionally not make any sense. You're basically tight-coupling the model with the controller. Usually the JPA entity (model) is a property of a JSF managed bean (controller). This keeps the code DRY. You don't want to duplicate the same properties over all place, let alone annotations on those such as bean validation constraints.
E.g.
#ManagedBean
#ViewScoped
public class Register {
private User user;
#EJB
private UserService service;
#PostConstruct
public void init() {
user = new User();
}
public void submit() {
service.create(user);
}
public User getUser() {
return user;
}
}
with this Facelets page (view):
<h:form>
<h:inputText value="#{register.user.email}" />
<h:inputSecret value="#{register.user.password}" />
<h:inputText value="#{register.user.firstname}" />
<h:inputText value="#{register.user.lastname}" />
...
<h:commandButton value="Register" action="#{register.submit}" />
</h:form>
See also:
What components are MVC in JSF MVC framework?
JSF Controller, Service and DAO
Contradictory explanations of MVC in JSF
JSF 2 reusing the validation defined in the JPA entities?
why shouldn't entity bean be managed by JSF framework?

JPA entities in JSF #ViewScoped backing bean always getting detached?

I'm currently trying to learn JSF and JPA. I know that the patterns I use are not recommended at all, but I want to understand what's going on because I think it'll help me in the future. I've just thrown together a prototype from various sources.
The problem that I encounter with the setup described below is that apparently the JPA entities are getting detached all the time, which in turn happens because the backing bean gets serialized over and over. In fact, if I remove the Serializable interface from the entity class, I get Exiting serializeView - Could not serialize state: com.sk.Message
Since the entities are detached, nothing gets committed to the database when I call EntityManager.commit(). If I manually merge all the entities (the commented out line in onCellEdit() below) with EntityManager.merge(), the modified entities are committed to the database.
I've already found from other SO posts that I could deal with this problem by adding
<context-param>
<param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
<param-value>false</param-value>
</context-param>
to my persistence.xml. But it was also pointed out somewhere that this would only be a workaround and not a solution.
So my questions are:
Is it intended/expected that a #ViewScoped JSF backing bean gets serialized over and over again (while staying on the same view all the time), which makes it difficult to use JPA entities in it?
Is it safe/reasonable to use the SERIALIZE_STATE_IN_SESSION parameter?
As I found recommended many times, should I just forget about JSF managed beans altogether and go with CDI directly (e.g. #ConversationScope to achieve something similar)?
I'm using TomEE (MyFaces, OpenJPA) with PrimeFaces. The backing bean contains the following code:
#ViewScoped
#ManagedBean
public class MessageBean implements Serializable
{
private List<Message> messages;
public List<Message> getMessages()
{
return messages;
}
public void setMessages( List<Message> messages )
{
this.messages = messages;
}
#PostConstruct
public void init()
{
messages = PersistenceManager.getInstance().queryMessages();
}
public void onCellEdit( CellEditEvent event )
{
// PersistenceManager.getInstance().mergeMessages( messages );
PersistenceManager.getInstance().commitTransaction();
}
[...]
A Message is a JPA Entity, like this:
#Entity
#Table( name = "message" )
#NamedQuery( name = "Message.findAll", query = "SELECT a FROM Message a" )
public class Message implements Serializable
{
private static final long serialVersionUID = 1L;
#Id
#Column( unique = true, nullable = false )
private Integer dbid;
#Column( nullable = false, length = 14 )
private String no;
[...]
}
The backing bean is referenced from a JSF page using a PrimeFaces DataTable:
<h:form id="navForm">
<p:dataTable
id="messages"
value="#{messageBean.messages}"
var="message"
editable="true"
editMode="cell">
<f:facet name="header">MESSAGE</f:facet>
<p:ajax
event="cellEdit"
listener="#{messageBean.onCellEdit}"
update=":navForm:messages" />
<p:column>
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{message.no}" />
</f:facet>
<f:facet name="input">
<p:inputText
id="modelInput"
value="#{message.no}" />
</f:facet>
</p:cellEditor>
<f:facet name="header">Message number</f:facet>
</p:column>
[...]
I know I'm probably violating dozens of best practices here, but for prototyping I've created a singleton POJO, PersistenceManager, which deals with the JPA interface (and potentially other data sources). I use an application-managed, resource-local EntityManager. An excerpt looks like this:
public class PersistenceManager
{
private static PersistenceManager INSTANCE;
private EntityManagerFactory emf;
private EntityManager em;
private EntityTransaction entr;
private PersistenceManager( PersistenceType persistenceType )
{
emf = Persistence.createEntityManagerFactory( "MessagePU" );
em = emf.createEntityManager();
}
public List<Message> queryMessages()
{
TypedQuery<Message> query = em.createNamedQuery( "Message.findAll", Message.class );
return query.getResultList();
}
public void commitTransaction()
{
if ( entr != null && entr.isActive() )
{
entr.commit();
}
}
[...]
Before committing a transaction you have to start it (then close it at the end of the transaction). Where is the else statement in your commitTransaction method, in case the EntityTransaction object is not active and/or null ?
Plus, I don't see any EJB in your code. The POJO approach is not the best option in an application managed, served, and hosted by a container.
For me, the best approach to implement the persistence layer in JSF and JavaEE applications in general, is the Session Façade Pattern, you can search the web about it, there are plenty of references.
In your case, something like this would do.
A Message Facade, that manages transactions related to the Message entity.
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
#Stateless
public class MessageFacade extends AbstractFacade<Message> {
#PersistenceContext(unitName = "MessagePU")
private EntityManager em;
#Override
protected EntityManager getEntityManager() {
return em;
}
public MessageFacade() {
super(Message.class);
}
public List<Message> queryMessages()
{
TypedQuery<Message> query = em.createNamedQuery( "Message.findAll", Message.class );
return query.getResultList();
}
}
An abstract facade class implementing generic persistence functions on generic entities.
public abstract class AbstractFacade<T> {
private Class<T> entityClass;
public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
}
protected abstract EntityManager getEntityManager();
public void create(T entity) {
getEntityManager().persist(entity);
}
public T edit(T entity) {
return getEntityManager().merge(entity);
}
public void remove(T entity) {
getEntityManager().remove(getEntityManager().merge(entity));
}
public T find(Object id) {
return getEntityManager().find(entityClass, id);
}
public List<T> findAll() {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
return getEntityManager().createQuery(cq).getResultList();
}
Your managed bean would then be something like :
#ViewScoped
#ManagedBean
public class MessageBean implements Serializable
{
#EJB
private MessageFacade messageFacade;
private List<Message> messages;
public List<Message> getMessages()
{
return messages;
}
public void setMessages( List<Message> messages )
{
this.messages = messages;
}
#PostConstruct
public void init()
{
messages = messageFacade.findAll();
}
public void onCellEdit( CellEditEvent event )
{
messageFacade.edit(messages);
}
}

JSF simple entity persistence from a form

I think that the question is simple, I get the error:
Caused by: java.lang.NullPointerException
at co.edu.unal.bienestar.dao.UserDao.save(UserDao.java:27)
at co.edu.unal.bienestar.facade.UserFacade.createUser(UserFacade.java:18)
at co.edu.unal.bienestar.mb.UserMB.createUser(UserMB.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.el.parser.AstValue.invoke(AstValue.java:262)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
... 27 more
When I try the create a new user, with a application which only have a entity class:
#Entity
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String username;
private String password;
private Role role;
<here getters and setters>
}
a Data Access Object:
public class UserDao {
#PersistenceContext
private EntityManager em;
public void save(User user) {
em.persist(user);
}
public void delete(User user) {
User userToBeRemoved = em.merge(user);
em.remove(userToBeRemoved);
}
public User update(User user) {
return em.merge(user);
}
public List<User> findAll() {
TypedQuery<User> query = em.createQuery(
"SELECT u FROM User u ORDER BY u.id", User.class);
return query.getResultList();
}
}
a facade:
public class UserFacade {
private UserDao userDao = new UserDao();
public void createUser(User user) {
userDao.save(user);
}
public List<User> listAll() {
List<User> result = userDao.findAll();
return result;
}
}
User Managed Bean:
#SessionScoped
#ManagedBean(name = "userMB")
public class UserMB implements Serializable {
public static final String INJECTION_NAME = "#{userMB}";
private static final long serialVersionUID = 1L;
private User user;
private UserFacade userfacade;
public User getUser() {
if (user == null) {
user = new User();
}
return user;
}
public void setUser(User user) {
this.user = user;
}
public void createUser() {
getUserfacade().createUser(user);
}
public UserFacade getUserfacade() {
if (userfacade == null){
userfacade = new UserFacade();
}
return userfacade;
}
}
And finally from JSF page I call the method like this:
<f:view>
<h:form>
<h1><h:outputText value="Create/Edit"/></h1>
<h:panelGrid columns="2">
<h:outputLabel value="Username:"/>
<h:inputText id="username" value="#{userMB.user.username}" title="username" />
<h:outputLabel value="Password:" />
<h:inputText id="password" value="#{userMB.user.password}" title="password" />
<h:outputLabel value="ID:" />
<h:inputText id="id" value="#{userMB.user.id}" title="id" />
</h:panelGrid>
<h:commandButton action="#{userMB.createUser}" value="create"/>
</h:form>
</f:view>
Where is my mistake?
#PersistenceContext works only in managed classes. Your UserDAO (and UserFacade) seems to be completely unmanaged and created manually. This way the EntityManager won't be injected at all. You'd need to manually create it as well. Right now it is null, which thus explains the NullPointerException.
Make the UserDAO (and UserFacade) a #Stateless EJB
#Stateless
public class UserDAO {
// ...
}
and use #EJB to inject them (and remove lazy loading in getter)
#EJB
private UserFacade userFacade; // Also on userDAO.
Or, if your environment doesn't support EJBs (e.g. Tomcat), then you'd need to either upgrade it to TomEE or to install OpenEJB on top of it, or to look for an alternate framework to manage your service facades and DAOs. Spring is often used, but why would you choose for it if Java EE 6 already offers the EJB3 awesomeness?
BalusC wrote: "#PersistenceContext works only in managed classes."
So, can it be an option to create the EntityManager in the UserMB by #PersistenceContext annotation, and pass it on to the DAO?
(I am aware that this is not the idea behind EE6, but if the alternatives are so complicated, one might think about this. Then you can stay with tomcat, and have a life cycle managed EntityManager, if I got this right.)
(Sorry for sending this as an answer instead of a comment, but i have to less points.)

JPA Entity as JSF Bean?

Does it make sense to use Entities as JSF Backing Beans?
#Entity
#ManagedBean
#ViewScoped
public class User {
private String firstname;
private String lastname;
#EJB
private UserService service;
public void submit() {
service.create(this);
}
// ...
}
Or is it better to keep them separately and transfer the data from the backing bean to the entity at the end?
#ManagedBean
#ViewScoped
public class UserBean {
private String firstname;
private String lastname;
#EJB
private UserService service;
public void submit() {
User user = new User();
user.setFirstname(firstname);
user.setLastname(lastname);
service.create(user);
}
// ...
}
You could do so. It's technically possible. But it does (design)functionally not make any sense. You're basically tight-coupling the model with the controller. Usually the JPA entity (model) is a property of a JSF managed bean (controller). This keeps the code DRY. You don't want to duplicate the same properties over all place, let alone annotations on those such as bean validation constraints.
E.g.
#ManagedBean
#ViewScoped
public class Register {
private User user;
#EJB
private UserService service;
#PostConstruct
public void init() {
user = new User();
}
public void submit() {
service.create(user);
}
public User getUser() {
return user;
}
}
with this Facelets page (view):
<h:form>
<h:inputText value="#{register.user.email}" />
<h:inputSecret value="#{register.user.password}" />
<h:inputText value="#{register.user.firstname}" />
<h:inputText value="#{register.user.lastname}" />
...
<h:commandButton value="Register" action="#{register.submit}" />
</h:form>
See also:
What components are MVC in JSF MVC framework?
JSF Controller, Service and DAO
Contradictory explanations of MVC in JSF
JSF 2 reusing the validation defined in the JPA entities?
why shouldn't entity bean be managed by JSF framework?

Resources