adam bien's blog

Simplest Possible JSF 2 / EJB 3.1 / JPA Component - With WAR Deployment 📎

The welcome.xhtml page uses facelets templating mechanism. It mainly consists of a textbox and a button:

         <ui:define name="body">
                <h:form>
                    <h:outputLabel value="Message:"/><h:inputText value="#{
messageview.message.message}"/>
                    <h:commandButton action="#{messageview.save}" value="Save"/>
                </h:form>
            </ui:define>

The InputText and the Button are value-bound to a @ManagedBean with the name MessageView:

@ManagedBean(name="messageview")
@RequestScoped
public class MessageView {
    @EJB
    MessageService messageService;

    private HelloMessage message;

    public MessageView() {
        this.message = new HelloMessage();
    }

    public HelloMessage getMessage() {
        return message;
    }

    public int getNumberOfMessages(){
        return messageService.getMessages().size();
    }


    public String save(){
        this.messageService.save(message);
        return "theend";
    }
}

The method save() returns "theend" String. This is the name of the next view. No page flow definitions in faces-config.xml are required. The MessageView managed bean instantiates and directly exposes the HelloMessage entity:

@Entity
@NamedQuery(name=HelloMessage.findAll,query="SELECT hm from HelloMessage hm")
public class HelloMessage{
    public final static String findAll = "com.abien.leancomp.business.message.entity.HelloMessage.findAll";

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String message;

    public HelloMessage() {
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

The actual business logic is implemented in a @Stateless no-interface view EJB 3.1:

@Stateless
public class MessageService {
    @PersistenceContext
    EntityManager em;

    public void save(HelloMessage hm){
        this.em.persist(hm);
    }

    public List<HelloMessage> getMessages(){
        return this.em.createNamedQuery(HelloMessage.findAll).getResultList();
    }
}

The MessageService manages the EntityManager and cares about transactions. Interestingly: the overall amount of code can be reduced with the introduction of a single EJB 3.1. You can use JSF 2 without EJBs, but then you will have to manage the persistence and transactions manually - what will result in significantly more code. You could expose the same EJB 3.1 as a RESTful service.

The whole example (LeanJSF2EJB31Component) was checked-in into: http://kenai.com/projects/javaee-patterns/. It was developed with Netbeans 6.8m1 and deployed to Glassfishv3b57.

Btw. the slowest "deployment" (with creation of the table) was: INFO: Deployment of LeanJSF2EJB31Component done is 895 ms

[The whole book "Real World Java EE Patterns - Rethinking Best Practices" describes lean Java EE architectures and patterns. See ServiceFacade, Service, PDO patterns and the chapter 6 "Pragmatic Java EE Architectures", Page 253]