tags:

views:

183

answers:

3

Hi all,

Can somebody recommend any framework to facilitate CRUD development in JSF 2.0?

Aspects I value most:

  • As lightweight as possible; limited dependencies on third party libraries
  • Support for an evolving domain model
  • Limited need for repetitive coding; support for scaffolding and/or metaannotations

Any hints highly appreciated! Yours, J.

+1  A: 

JSF 2.0 itself. CRUD is very easy to do with JSF alone - no need for any other framework. You need

  • 1 managed bean (annotated with @ManagedBean)
  • 2 xhtml pages (facelets) - one for list and one for edit/create
  • A <h:dataTable> with anedit link/button, by which you set the current row object in the managed bean (using action="#{bean.edit(currentRowObject)}"). (In JSF 1.2 this was achieved by <f:setPropertyActionListener>)
  • Action methods (void, with no arguments) to handle the operations
  • @PostConstruct to load the data initially.
Bozho
Hi Bozho,Thank you for the reply.I've added an additional 'requirement' to the original question: Limited need for manual coding. I understand your answer, but on a large domain model, the manual approach remains cumbersome.I'm wondering if somthing Grails-like exists, but in pure JSF.Thank you , J.
Jan
Isn't setPropertyActionListener unneeded in JSF 2.0, as we can pass objects as arguments?
Thorbjørn Ravn Andersen
@Thorbjørn Ravn Andersen indeed. thanks for reminding me. added to the answer.
Bozho
+4  A: 

CRUD is indeed a piece of cake using JSF 2.0 provided standard facility: a @ViewScoped bean in combination with a h:dataTable backed by a DataModel<E> basically already suffices. Here's a code example which is shamelessly copied from this article.

Bean:

package mypackage;

import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;

@ManagedBean
@ViewScoped
public class Bean {

    private List<Item> list;
    private DataModel<Item> model;
    private Item item = new Item();
    private boolean edit;

    public Bean() {
        // list = dao.list();
        // Actually, you should retrieve the list from DAO. This is just for demo.
        list = new ArrayList<Item>();
        list.add(new Item(1L, "item1"));
        list.add(new Item(2L, "item2"));
        list.add(new Item(3L, "item3"));
        model = new ListDataModel<Item>(list);
        System.out.println("bean constructed and model loaded"); // Cough, logger, cough.
    }

    public void add() {
        // dao.create(item);
        // Actually, the DAO should already have set the ID from DB. This is just for demo.
        item.setId(list.isEmpty() ? 1 : list.get(list.size() - 1).getId() + 1);
        list.add(item);
        item = new Item(); // Reset placeholder.
    }

    public void edit() {
        item = model.getRowData();
        edit = true;
    }

    public void save() {
        // dao.update(item);
        item = new Item(); // Reset placeholder.
        edit = false;
    }

    public void delete() {
        // dao.delete(item);
        list.remove(model.getRowData());
    }

    public List<Item> getList() {
        return list;
    }

    public DataModel<Item> getModel() {
        return model;
    }

    public Item getItem() {
        return item;
    }

    public boolean isEdit() {
        return edit;
    }

    // Other getters/setters are actually unnecessary. Feel free to add them though.

}

Page:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"&gt;
    <h:head>
        <title>Really simple CRUD</title>
    </h:head>
    <h:body>
        <h3>List items</h3>
        <h:form rendered="#{not empty bean.list}">
            <h:dataTable value="#{bean.model}" var="item">
                <h:column><f:facet name="header">ID</f:facet>#{item.id}</h:column>
                <h:column><f:facet name="header">Value</f:facet>#{item.value}</h:column>
                <h:column><h:commandButton value="edit" action="#{bean.edit}" /></h:column>
                <h:column><h:commandButton value="delete" action="#{bean.delete}" /></h:column>
            </h:dataTable>
        </h:form>
        <h:panelGroup rendered="#{empty bean.list}">
            <p>Table is empty! Please add new items.</p>
        </h:panelGroup>
        <h:panelGroup rendered="#{!bean.edit}">
            <h3>Add item</h3>
            <h:form>
                <p>Value: <h:inputText value="#{bean.item.value}" /></p>
                <p><h:commandButton value="add" action="#{bean.add}" /></p>
            </h:form>
        </h:panelGroup>
        <h:panelGroup rendered="#{bean.edit}">
            <h3>Edit item #{bean.item.id}</h3>
            <h:form>
                <p>Value: <h:inputText value="#{bean.item.value}" /></p>
                <p><h:commandButton value="save" action="#{bean.save}" /></p>
            </h:form>
        </h:panelGroup>
    </h:body>
</html>

Further, Netbeans has some useful wizards to genreate a CRUD application based on a datamodel.

BalusC
ah, I looked for that article but couldn't find it. And was lazy to give a complete example myself :) (+1)
Bozho
Yeah, the example code is appreciated. Still I'm wondering if there isn't a way to generate all this code, driven by a set of annotated Entity objects.
Jan
The answer doesn't fully fit all requirements I had in mind. Though, it looks like the best answer available, so I'll mark it as accepted. (I'm new to StackOverflow... Is this the right thing to do?)
Jan
You can also consider using Netbeans' builtin wizards. I edited the answer to include a link.
BalusC
+1  A: 

I found this article useful as well:

Conversational CRUD in Java EE 6

http://www.andygibson.net/blog/tutorial/pattern-for-conversational-crud-in-java-ee-6/

By Andy Gibson

Jan