Dashboard > Struts University > Home > JPA Training Course > JPA Agenda > Register-JPA-Notes
Register-JPA-Notes
Added by Ted Husted, last edited by Ted Husted on Dec 07, 2007  (view change)
Labels: 
(None)


How do we bridge the gap between object entities and database tables?

Presentation - Mapping Object Graphs to Relational Data

With a development infrastructure in place, we take a closer look at object relational modeling, exploring the various types of relationships and associations objects share.

  • What are object graphs?
  • How do we map properties?
  • How do we map relationships?
  • How do we map inheritance?

Workshop - Register, Profile

In the lab, we move over to the Struts MailReader use cases, and create a user entity object.

Story: Subscribers can create, store, and update a user account with the system.

  • Design user entity object
  • Create / Read / Update / Delete user entity

Prerequisites

  • JPA-enabled application with database connection
  • EntryManagerHelper
  • EntityTestCase
  • Example TestCase

New Dependencies

  • Copy the entity.EntityService class from the register project into your project.

Exercises

  • Continue using code from a prior workshop (or import "register" from courseware as new MailReader project)
  • Review Register and Profile use cases
  • Implement Main Success Scenarios only (no validation)
  • Create the User class, and any helper classes, in a entity.user package (under src/main.
  • Create a UserService class to encapsulate the persistence methods. Use EntityService as a base class (see hint code).
  • Skip any references to the Subscription entity for now.

Hint Code

@Entity
    @Table(name = "APP_USER")
    @NamedQueries( {
    @NamedQuery(name = "User.COUNT", query = "SELECT COUNT(*) FROM USER") })
    public class User extends implements Serializable {
    
    private String from_address;
    public String getFromAddress() {
    return from_address;
    }
    public void setFromAddress(String value) {
    from_address = value;
    // ...
    }
package entity.user;
    import javax.persistence.PersistenceException;
    import entity.EntityService;
    public class UserService extends EntityService {
    
    public int count() throws PersistenceException {
    Long count = (Long) singleResult("User.COUNT", null, null);
    int result = count.intValue();
    return result;
    }
    
    public User create(User value) throws PersistenceException {
    return (User) createEntity(value);
    }
    
    // ...
    }
package entity;
    import java.util.List;
    import javax.persistence.EntityManager;
    import javax.persistence.NoResultException;
    import javax.persistence.PersistenceException;
    import javax.persistence.Query;
    public class EntityService {
    
    public Object createEntity(Object value) throws PersistenceException {
    EntityManager manager = EntityManagerHelper.getEntityManager();
    manager.persist(value);
    return value;
    }
    
    public Object deleteEntity(Object value) throws PersistenceException {
    EntityManager manager = EntityManagerHelper.getEntityManager();
    manager.merge(value);
    manager.remove(value);
    return value;
    }
    
    @SuppressWarnings("unchecked")
    public List resultList(String namedQuery, String parameterName, String value) {
    EntityManager manager = EntityManagerHelper.getEntityManager();
    List result = null;
    Query query = manager.createNamedQuery(namedQuery);
    if (parameterName != null)
    query.setParameter(parameterName, value);
    try {
    result = query.getResultList();
    } catch (NoResultException e) {
    result = null;
    }
    return result;
    }
    
    public Object singleResult(String namedQuery, String parameterName,
    String value) {
    EntityManager manager = EntityManagerHelper.getEntityManager();
    Object result = null;
    Query query = manager.createNamedQuery(namedQuery);
    if (parameterName != null)
    query.setParameter(parameterName, value);
    try {
    result = query.getSingleResult();
    } catch (NoResultException e) {
    result = null;
    }
    return result;
    }
    
    @SuppressWarnings("unchecked")
    public Object readEntity(Class entity, String id) {
    EntityManager manager = EntityManagerHelper.getEntityManager();
    Object result = null;
    try {
    result = manager.find(entity, id);
    } catch (NoResultException e) {
    result = null;
    }
    return result;
    }
    
    public Object updateEntity(Object value) throws PersistenceException {
    EntityManager manager = EntityManagerHelper.getEntityManager();
    manager.merge(value);
    return value;
    }
    }
package entity;
    import java.util.Random;
    import javax.persistence.EntityManager;
    import junit.framework.TestCase;
    public class EntityTestCase extends TestCase {
    
    protected EntityManager manager;
    protected boolean rollback = false;
    protected String base;
    protected Random generator;
    
    protected String nextBase() {
    int r = generator.nextInt();
    return String.valueOf(r);
    }
    
    protected boolean isNotEmpty(String value) {
    return (value != null) && (value.length() > 0);
    }
    
    public void setUp() throws Exception {
    super.setUp();
    generator = new Random();
    base = nextBase();
    manager = EntityManagerHelper.getEntityManager();
    EntityManagerHelper.beginTransaction();
    }
    
    public void tearDown() throws Exception {
    super.tearDown();
    if (rollback)
    EntityManagerHelper.rollback();
    EntityManagerHelper.commit();
    EntityManagerHelper.closeEntityManager();
    }
    
    public void testTrue() throws Exception {
    assertTrue(true);
    }
    
    }
private User newUser() {
    return new User("user_" + base, "pass_" + base); // or UserImpl
    }

Other hints

  • To delete the database and start over, stop Derby, delete the /Derby/mailreader folder, and start Derby. The database should be recreated the next time the EntityManagerHelper is invoked.

Accomplishments

  • Designed user entity object
  • Created / Read / Updated / Deleted user entity

Extra Credit

  • Specify a column length of 64 for full_name, from_address, reply_to_address
  • Refactor the entity.user objects to use an interface and implementation class. Use the original class name for the interface name, and add an "Impl" suffix to the default class name (e.g. User, UserImpl, UserService, UserServiceImpl).
  • Review the EntityService class. How does this base class make coding easier? Why not push code like this down into the entity classes?
  • Discuss with your coding partner: Given a standard persistence technology, do service classes help or hinder? Data access objects? (not shown)

Extensive Extra Credit

  • Add a base UuidEnity class with helper methods for managing an ID property based on a universally unique identifier (UUID).
  • Refactor User to use the UuidEntity class (assign ID in constructor).

Extensive Extra Credit Hint Code

public class UuidEntity implements Serializable {
    
    @Transient
    private UUID uuid;
    
    @Id
    @Column(length = 36)
    private String id;
    
    public String getId() {
    return id;
    }
    
    public void setId(String value) {
    id = value;
    }
    
    @Version()
    private Timestamp last_update;
    
    public Timestamp getLastUpdate() {
    return last_update;
    }
    
    public void setLastUpdate(Timestamp value) {
    last_update = value;
    }
    
    public boolean equals(Object obj) {
    if ((obj instanceof UuidEntity) && (getId() != null)) {
    return getId().equals(((UuidEntity) obj).getId());
    } else {
    return false;
    }
    }
    
    public int hashCode() {
    if (getId() != null) {
    if (uuid == null)
    uuid = UUID.fromString(id);
    return uuid.hashCode();
    } else {
    return super.hashCode();
    }
    }
    
    public String toString() {
    return "entity.UuidEntity[id=" + getId() + "]";
    }
    
    public UuidEntity() {
    String id = UUID.randomUUID().toString();
    setId(id);
    }
    }

Site running on a free Atlassian Confluence Open Source Project License granted to OSS. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.5 Build:#811 Jul 25, 2007) - Bug/feature request - Contact Administrators