J3 Limited
 
Google
WWW J3Ltd
 
User Registration EJB's

Introduction

The previous section setup the Eclipse project, namely:

  • A default page
  • An error page
  • A Welcome page
  • Internationalization (supports english and french)

In this section the process of registratering is written.

The source code is available in a zip archive here.

The registration page allows a new user to register their details to become a member of MyCV. The entity EJB's and the session EJB are written here, along with their supporting classes and files. The web application, in the next chapter , makes use of the EJB's written in this chapter.

The database used in this section was created in the installation tests.

Entity EJB's

The database currently has two tables: Person and Address. The EJB's are created in Eclipse. In Eclipse it is very easy to create a bean: All the private members are entered, then by right clicking on the code inside the class, the popup menu option "Generate Getters and Setters" is selected. This generates the methods to get and set the field values.

The Address entity is shown below. The primary key is annotated as @Id @GeneratedValue to specify that the database engine generates the primary key value.

package com.j3ltd.server.entities;


import java.io.Serializable;
import javax.persistence.*;


@Entity
public class Address implements Serializable {
  private int id;
  private String line1;
  private String line2;
  private String line3;
  private String line4;
  private String postcode;
  private String country;
  
  public String getCountry() {
    return country;
  }
  public void setCountry(String country) {
    this.country = country;
  }
  
  @Id
  @GeneratedValue
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getLine1() {
    return line1;
  }
  public void setLine1(String line1) {
    this.line1 = line1;
  }
  public String getLine2() {
    return line2;
  }
  public void setLine2(String line2) {
    this.line2 = line2;
  }
  public String getLine3() {
    return line3;
  }
  public void setLine3(String line3) {
    this.line3 = line3;
  }
  public String getLine4() {
    return line4;
  }
  public void setLine4(String line4) {
    this.line4 = line4;
  }
  public String getPostcode() {
    return postcode;
  }
  public void setPostcode(String postcode) {
    this.postcode = postcode;
  }
}

The Person entity is shown below. The primary key is annotated, as done for the Address entity. A relationship is annotated, to specify that a person entity has one address, using the addressId database field in the table Person. This allows the Person EJB to have a member of the type Address. The EJB server handles the task of going to the Address table to get or change the data. The cascade type for the Address is set to CascadeType.ALL, this should ensure that when a Person record is deleted, the corresponding Address record is also deleted.

package com.j3ltd.server.entities;


import java.io.Serializable;
import javax.persistence.*;


@Entity
public class Person implements Serializable {
  private int id;
  private String email;
  private String password;
  private String firstName;
  private String lastName;
  private String title;
  private String gender;
  private java.util.Date dateOfBirth;
  private String suffix;
  private String daytimePhone;
  private String eveningPhone;
  private String webSite;
  private String maritalStatus;
  private Address address;
  private String localeLanguage;
  private String localeCountry;

  public String getLocaleCountry() {
    return localeCountry;
  }
  public void setLocaleCountry(String localeCountry) {
    this.localeCountry = localeCountry;
  }
  public String getLocaleLanguage() {
    return localeLanguage;
  }
  public void setLocaleLanguage(String localeLanguage) {
    this.localeLanguage = localeLanguage;
  }
  @Id
  @GeneratedValue
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }  
  
  @ManyToOne(cascade=CascadeType.ALL)
  @JoinColumn(name="addressId", 
          referencedColumnName="id")
  public Address getAddress() {
    return address;
  }
  public void setAddress(Address address) {
    this.address = address;
  }
  public java.util.Date getDateOfBirth() {
    return dateOfBirth;
  }
  public void setDateOfBirth(java.util.Date dateOfBirth) {
    this.dateOfBirth = dateOfBirth;
  }
  public String getDaytimePhone() {
    return daytimePhone;
  }
  public void setDaytimePhone(String daytimePhone) {
    this.daytimePhone = daytimePhone;
  }
  
  public String getEmail() {
    return email;
  }
  public void setEmail(String email) {
    this.email = email;
  }
  public String getEveningPhone() {
    return eveningPhone;
  }
  public void setEveningPhone(String eveningPhone) {
    this.eveningPhone = eveningPhone;
  }
  public String getFirstName() {
    return firstName;
  }
  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }
  public String getGender() {
    return gender;
  }
  public void setGender(String gender) {
    this.gender = gender;
  }
  public String getLastName() {
    return lastName;
  }
  public void setLastName(String lastName) {
    this.lastName = lastName;
  }
  public String getMaritalStatus() {
    return maritalStatus;
  }
  public void setMaritalStatus(String maritalStatus) {
    this.maritalStatus = maritalStatus;
  }
  public String getSuffix() {
    return suffix;
  }
  public void setSuffix(String suffix) {
    this.suffix = suffix;
  }
  public String getTitle() {
    return title;
  }
  public void setTitle(String title) {
    this.title = title;
  }
  public String getWebSite() {
    return webSite;
  }
  public void setWebSite(String webSite) {
    this.webSite = webSite;
  }
  public String getPassword() {
    return password;
  }
  public void setPassword(String password) {
    this.password = password;
  }
}

Stateless Session EJB

A stateless session EJB is coded, it is through this EJB that the web application accesses the entities.

package com.j3ltd.server.session;


import javax.ejb.*;
import com.j3ltd.server.entities.*;
import javax.persistence.*;
import com.j3ltd.server.sessionremote.*;
import com.j3ltd.server.Exceptions.*;


@Stateless
public class EntityFacadeBean implements EntityFacade {
  @PersistenceContext(unitName="shoestringPU") EntityManager em;
    
  public Person getPerson(String email) {
    Person entity = null;
    try {
      Query query = em.createQuery("SELECT p FROM Person p WHERE p.email = ?1");
      query.setParameter(1, email);
      entity = (Person) query.getSingleResult();
    }
    catch (NoResultException noneFound) {
      // if not found, just return null
    }
    return entity;
  }
  
    /**
   * Perform last minute validation, then if OK save 
   * entities (Person and Address in Person)
   * @param toCreate person record to persist
   * @return person record just created, with the
   *     primary key set to that just insrted.
   *  @throws PersonEntityExistsException if email given exists
   *  @throws PersonPasswordException if password is < 6 characters long
   *  @throws PersonEmailException if email is blank or null
   */
  public Person createPerson(Person toCreate) 
    throws PersonEntityExistsException,  PersonPasswordException,
           PersonEmailException {  
    String email = toCreate.getEmail();
    if (email == null || email.trim().length() == 0) {
      throw new PersonEmailException("Length is zero");
    }
    String password = toCreate.getPassword();
    if (password == null || password.length() < 6) {
      throw new PersonPasswordException("Length is less than 6");
    }
    if (getPerson(email) != null) {
      throw new PersonEntityExistsException(
                  "Person record already exists with an email of " + 
                  toCreate.getEmail());
    }
    em.persist(toCreate);
    return toCreate;
  }
}  

The class has two methods. The first is to find a Person record using the email value. The other method is used to create a new Person record. The Person table has defined a UNIQUE index on the email field. CreatePerson() throws a PersonEntityExistsException if a person with the email already exists. PersonEmailException is thrown, if the email is blank or null. PersonPasswoprdException is thrown, if the password is too short. At the time of writing, the EJB specification mentions EntityExistsException, but it does not seem to be documented, and the release of JBoss used does not have it, hence the need to define our own PersonEntityExistsException.

The application exceptions are defined as follows:

PersonEntityExistsException:

package com.j3ltd.server.exceptions;


/**
* Currently the javadocs on EntityExistsException do not exist
* in the JEE5 beta sdk docs. When it appears, this exception 
* will be removed, and all references replaced by 
* EntityExistsException.
*/
public class PersonEntityExistsException extends Exception {
  public PersonEntityExistsException(String message) {
    super(message);
  }
}

PersonEmailException:


package com.j3ltd.server.exceptions;


public class PersonEmailException extends Exception {
  public PersonEmailException(String message) {
    super(message);
  }
}

PersonPasswordException:


package com.j3ltd.server.exceptions;


public class PersonPasswordException extends Exception {
  public PersonPasswordException(String message) {
    super(message);
  }
}

The session ejb has a remote interface defined as follows:

package com.j3ltd.server.sessionremote;


import javax.ejb.*;

import com.j3ltd.server.entities.*;
import com.j3ltd.server.exceptions.PersonEmailException;
import com.j3ltd.server.exceptions.PersonEntityExistsException;
import com.j3ltd.server.exceptions.PersonPasswordException;


@Remote
public interface EntityFacade {
  public Person createPerson(Person toCreate) 
    throws PersonEntityExistsException, 
           PersonPasswordException, 
           PersonEmailException;
  public Person getPerson(String email);
}

Persistence XML File

The persistence unit that the session EJB uses is defined in a file called persistence.xml, which is in the "src" folder:

<?xml version="1.0" encoding="UTF-8"?>

<persistence>
  <persistence-unit name="shoestringPU">>
      <jta-data-source>java:/ShoestringDS</jta-data-source>
    <properties>
      <property name="hibernate.dialect" 
        value="org.hibernate.dialect.MySQLDialect"/>
    </properties>    
  </persistence-unit>
</persistence>

Packaging The EJB's

At this point, all the EJB code for the registration process is complete. The packaging configuration is updated within Eclipse as follows.

The project properties dialog is selected, the "Packaging Configurations" tab is selected and the "Add..." button is pressed:

The archive name entered is "MyCV.jar", "OK" is pressed.

The archive is right clicked, and "Add Folder" is selected from the popup menu.

The project bin folder com/j3ltd/server is selected. The "includes" field has **.*.class to select all the java classes in the server folder. The prefix entered is com/j3ltd/server, so that the correct Java package tree is created.

The archive is right clicked and "Add File" is selected from the popup menu. The project source file jndi.properties is added. Then the project file persistence.xml is added with a prefix of "META-INF". The packaging configuration should look like the screenshot below:

This completes the EJB's and supporting files. The next step is to update the web application with a new JSF page, and some supporting code.

  Copyright © 2006 J3 Ltd Permission is granted to reproduce material on this page, on the condition that a reference to "WWW.J3Ltd.com" is given as the source of the material.