1

I am just learning java ee 6. My goal is having a simple crud application which let me create edit list and delete one trivial entity made simply by the id, a name string and a description string. I followed this just to see some code http://netbeans.org/kb/docs/web/jsf20-crud.html I used eclipse instead of netbeans and jboss 7 instead of glass fish. Well.... It works.

Now think my entity is a "User": id, username, Password. I want to add a "UserRole" entity and here it is: id, rolename. Then I set a OneToMany and a ManyToOne relationship.

So, how can I manage the role input in the create user page? Netbeans crud suggested code is a selectonemenu (a select drop down list) with all the roles ids as values. On form submit a static inner class "roleconverter" (a facesconverter) in the role controller (the jsf managed bean) takes the selected and submitted role Id string and looks up for the corresponding role using a ejb-dao.

My questions are:

  • do I understand? Is what I wrote above correct?
  • is using a converter in that way the best best practice? Doesn't a better solution exist for such a simple and recurrent task?
  • converters for entities are all the same except for the entity name, how can I remove the duplication, for example with a generic converter?
  • what's the best GUI in your opinion for managing many to many in jsf 2? (e.g. A user with multiple roles scenario)
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Fabio B.
  • 9,138
  • 25
  • 105
  • 177

1 Answers1

0

That's correct. The converter is required because HTML is basically one big String and HTTP request parameters are all Strings. HTML and HTTP doesn't understand nor pass around concrete Java objects. They live in webserver's memory only. You'd really need to be able to convert between SomeRandomEntity and String in order to generate HTML response and parse HTTP request parameters properly.

As to the converters being not really DRY, if all your entities extend a common base entity wherein the @Id is definied along with the getter and setter, and you've a generic DAO, then you could create a generic converter for this. Something like this (trivial prechecking and ConverterException handling omitted):

@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
    if (value == null) {
        return null;
    }

    Long id = ((BaseEntity) value).getId();
    return String.valueOf(id);
}

@Override
@SuppressWarnings("unchecked")
public Object getAsObject(FacesContext context, UIComponent component, String value) {
    if (value == null) {
        return null;
    }

    Long id = Long.valueOf(value);
    Class<BaseEntity> type = (Class<BaseEntity>) component.getValueExpression("value").getType(context.getELContext());
    return genericDAO.find(id, type);
}

Alternatively, in the particular case of <h:selectOneMenu>, you could also use a converter which converts based on the object values of <f:selectItem(s)>. This is however not exactly trivial. The JSF2 component library OmniFaces has such a SelectItemsConverter in its assortiment. You may want to check its source code if interested.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555