Automatically Populating a JPA Bean - geetools/geemvc GitHub Wiki

geeMVC will go even further than simple bean population when it:

  1. Finds the @Data annotation.
  2. Recognizes that the object is a JPA bean.

In the following example we will show you a very simplistic JPA bean so that you get the general idea. Obviously there is a lot more to JPA and geeMVC plays very well with it, but to get a more in-depth understanding of what JPA is and what you can do with it, you may want to check out the tutorial Understanding JPA, Part 1.

The Controller

In the previous section we created the AccountController with the 2 simple methods showForm() and processForm(AccountForm accountForm). Here we showed you how you can directly populate a standard Java bean. That is nice, but what if we wanted to update an existing object? We would need to load the data from the database first. With the @Data annotation geeMVC can take care of this for you - provided that we are dealing with a JPA bean.

geeMVC recognizes a JPA bean by looking for its @javax.persistence.Entity annotation. In order to find the concrete bean however, geeMVC also needs the unique id or primary key property. geeMVC solves this by searching the bean for a field marked with a @javax.persistence.Id annotation. Once found, the name of the bean property is resolved and an attempt is made to find a matching request parameter - which can be a path parameter or a query string parameter. Should everything succeed up to this point, geeMVC will inject the JPA entity manager and load the bean.

If request parameters exist for that bean, i.e. beanName.propertyName, these will automatically override the existing bean values. In your controller you will now have the updated bean object and you simply need to tell the javax.persistence.EntityManager to update the database.

package com.example;

@Controller
@Request("/accounts")
public class AccountController {

    @Request("form")
    public String showForm() {
        return "view: account/form";
    }

    @Request(path = "add")
    public String createAccount(AccountForm accountForm) {

        // Form bean is processed and saved to database ...

        return "view: account/success";
    }

    @Request(path = "update/{id}")
    public String updateAccount(@Data AccountBean accountBean) {

        // Update the account bean with an injected entity manager ...
        entityManager.merge(accountBean);

        return "view: account/success";
    }
}

The JPA Entity Bean

The following code shows an example of a JPA entity bean. Note two important things so that geeMVC can automatically find the correct bean:

  1. The bean must be annotated with @javax.persistence.Entity.
  2. The bean must have a field marked with the @javax.persistence.Id annotation.
package com.example;

@Entity
@Table(name = "account")
public class AccountBean implements Serializable {
    private static final long serialVersionUID = 2624141428167987843L;

    @Id
    @GeneratedValue
    protected Long id = null;
    protected String username = null;
    protected String password = null;
    protected String forename = null;
    protected String surname = null;
    protected String email = null;
    protected int age;

    public Long getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getForename() {
        return forename;
    }

    public void setForename(String forename) {
        this.forename = forename;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

Now that we have learnt how to bind parameters to our handler method, lets find out how we can validate them.