what to use, managed beans (backing beans) or entity beans?

I see a lot of examples marking beans as entity beans (@Entity) & named beans (CDI), so as to avoid creating 2 classes (managed bean & entity bean) and also to make use of Bean Validation so that validation can be performed on both client & server.

So should I be using a single class or not, are there any issues or should I be having my managed beans or service layer create entity beans using the data from managed beans ?


The @Named or @ManagedBean annotations are typically used to let the bean container (CDI/JSF) create an instance of a bean on demand when referenced by expression language in JSF.

For an @Entity bean, it often doesn't make that much sense to just get an arbitrary new instance. An @Entity is very strongly connected to a persistent identity. Such an entity is therefor requested from the Entity Manager and not from a bean container.

The typical pattern is to have a (slim) backing bean that's named making a call to a service (which is in turn typically @Stateless in Java EE). The service then returns entities.

In some very trivial systems people sometimes do make the service named and thus directly available to EL. However, eventually you often want to let the "backing code" generate faces messages or handle (table) selections, which are all things that should not be the concern of a pure business service.

Another common shortcut is letting the backing bean contain business code directly (e.g. the entity manager that retrieves the entities). This makes the business code hard to re-use, but if the app is trivial and there's no need for re-use you might get away with it.

But letting the entity -be- the backing bean is rare and anti to the common Java EE patterns.

Just note that the backing bean can return the entity directly, so bean-validation can still be used. There is no need whatsoever for the strange 'scatter/gather' pattern that crept up a long time ago (See the second example in this question).

E.g.

@ViewScoped
@ManagedBean
public class BackingBean {

     private SomeEntity myEntity; // + getter

     @EJB  
     private Service service;

     @PostConstruct
     public void init() {
         myEntity = service.getSomeEntity();
     }

     public void save() {
         service.save(myEntity);
         FacesContext.getCurrentInstance().addMessage(..., ...);
     }
 }

Assuming SomeEntity in an @Entity annotated bean, bean validation can now be used on a Facelet like:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
>    
    <h:body>   
        <h:form>      
            <h:inputText value="#{backingBean.myEntity.name}" />                        
            <h:commandButton value="Save" action="#{backingBean.save}" />
        </h:form>            
    </h:body>
</html>

If there's a constraint on SomeEntity.name it will be validated.