Building applications with Errai and JPA

User Rating: 0 / 5

Star InactiveStar InactiveStar InactiveStar InactiveStar Inactive
 

In this second tutorial abut JBoss Errai we will show how to use JPA to store and retrieve objects on the client side.

JPA support has been introduced in Errai starting from the release 2.1 allowing the developer to use the browser's local storage as database for your application. This means that objects are stored and fetched from the browser's local storage and not from the JPA provider on the server side.

This allows transparent reusing the JPA-related code between the client and the server. As a matter of fact the JPA persistence.xml file will be used when running the server-side application but will be ignored when running the application on the client.

So how to write a simple Entity class to be used by Errai JPA ? not much differently from an ordinary Entity:


@NamedQueries ({
  @NamedQuery(name="allUsers", query="SELECT a FROM User a ORDER BY a.birthday"),
  @NamedQuery(name="UserByName", query="SELECT a FROM User a WHERE a.name=:name")
})
@Portable @Entity
public class User {

  @GeneratedValue
  @Id
  private Long id;

  private String name;

   
  private Date birthday;

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }
 

  public Date getBirthday() {
    return birthday;
}

public void setBirthday(Date birthday) {
    this.birthday = birthday;
}

public void setName(String name) {
    this.name = name;
  }
  
}

 

As you can see, the only new annotation added to this class is org.jboss.errai.common.client.api.annotations.Portable which makes this class eligible for serialization with Errai Marshalling.

Now let's write a Form which can be used to populate this Entity and another one to display the data in a tabular form:

public class UserForm extends Composite {

 

  private final EntityManager em;

  private final User user;

  private final TextBox name = new TextBox();
 
  private final DatePicker birthday = new DatePickerWithYearSelector();

  private final Button saveButton = new Button("Save");

  private RowOperationHandler<User> saveHandler;

  public UserForm(final User user, EntityManager em) {
    this.user = user;
    this.em = em;

    saveButton.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
          updateUserFromUI();
        if (saveHandler != null) {
          saveHandler.handle(user);
        }
      }
    });

    updateUIFromUser();

    Grid g = new Grid(5, 2);

    int row = 0;
    g.setText(row, 0, "Name:");
    g.setWidget(row, 1, name);

    row++;
    g.setText(row, 0, "Birthday:");
    g.setWidget(row, 1, birthday);

    row++;
    g.setWidget(row, 1, saveButton);

    initWidget(g);
  }

  protected void updateUserFromUI() {
    user.setName(name.getText()); 
    user.setBirthday(birthday.getValue());
  }

  private void updateUIFromUser() {

    name.setText(user.getName());
  
    if (user.getBirthday() != null) {
        birthday.setValue(user.getBirthday());
        birthday.setCurrentMonth(user.getBirthday());
    }
  }

  public void setSaveHandler(RowOperationHandler<User> handler) {
    this.saveHandler = handler;
  }

  public void grabFocus() {
    name.setFocus(true);
  }
}

As you can see, the Main class gets injected the EntityManager just like a standard Java EE application. Besides this a set of widgets are added to the GUI, such as the TextBox for entering the User name, a DatePicker for picking the User's birthday and a Save Button for persisting the data. Whenever the Save button is clicked, an event is raised, which will ultimately invoke the updateUserFromUI method to keep in sync the GUI and the database.

 

This class which uses a very simple plain GWT layout that can be further enhanced using the ErraiUI, UIBuilder and Errai Data Binding. See this example  for a full-on Errai development experience.

 

The last piece of code we will show here is the UserTable which extends a standard GWT com.google.gwt.user.client.ui.FlexTable and adds a sets of RowOperationHandler for endling the edit/delete operations:

public class UserTable extends FlexTable {

  private RowOperationHandler<User> deleteHandler;
  private RowOperationHandler<User> editHandler;

  public UserTable() {
    addStyleName("userTable");

    ColumnFormatter cf = getColumnFormatter();
    cf.setStyleName(0, "userName");
    cf.setStyleName(1, "birthday");
    cf.setStyleName(2, "deleteButton");
  }

  public void addAll(List<User> entries) {
    for (User a : entries) {
      add(a);
    }
  }

  public void add(final User a) {

    Button editButton = new Button("Edit...");
    editButton.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        if (editHandler != null) {
          editHandler.handle(a);
        }
      }
    });

    Button deleteButton = new Button("Delete");
    deleteButton.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        if (deleteHandler != null) {
          deleteHandler.handle(a);
        }
      }
    });

    int row = getRowCount();
    insertRow(row);
    insertCells(row, 0, 3);
    setText(row, 0, a.getName());
    setText(row, 1, a.getBirthday() == null ? "" :
      DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT).format(a.getBirthday()));
    setWidget(row, 2, editButton);
    setWidget(row, 3, deleteButton);
  }

  public void setDeleteHandler(RowOperationHandler<User> handler) {
    deleteHandler = handler;
  }

  public void setEditHandler(RowOperationHandler<User> handler) {
    editHandler = handler;
  }
}

We will not include all the single classes of this demo application (which is a simplified version of the JPA basic demo); you can however download at the bottom of this tutorial the Maven JPA project for running it.
Finally, here's the *.gwt.xml file which includes CDI and JPA module:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.6//EN"
        "http://google-web-toolkit.googlecode.com/svn/releases/1.6/distro-source/core/src/gwt-module.dtd">
<module rename-to="ErraiJpaDemo">

  <inherits name="org.jboss.errai.jpa.JPA" />
  <inherits name="org.jboss.errai.enterprise.CDI" />
  <inherits name='com.google.gwt.user.theme.clean.Clean'/>

</module>

And here's the application in action:

errai jboss tutorial

Download the source of this example.


Advertisement