Home > Articles > Data > MySQL

End-to-End JPA Collections with MySQL, Part 1

  • Print
  • + Share This
Having difficulty getting your JPA collection code up and running? It's tricky but not impossible to get up to speed in this increasingly critical area. Stephen Morris demonstrates an end-to-end, working example of a JPA collection in this first part of a two-part series.
Like this article? We recommend

Like this article? We recommend

End-to-End JPA Collections with MySQL, Part 1

It's all about data nowadays and for good reason. In an increasingly online world, the value of data is massive, and it's plain to see how organizations walk a tightrope when it comes to data. Why the tightrope? Well, it's because big data is big money, and getting access to data may involve some degree of privacy violation.

Aside from the business issues, at the heart of the matter there is one dominant technology: relational databases. The information that resides in databases can now be counted on to far outlive the applications used to create it. So, a solid knowledge of the database area is a good investment for programmers who are keen to move up the value chain.

In this two-part article series, I'll be demonstrating how to create a collection-based JPA model and how to implement this using MySQL. In Part 2, I'll look at an increasingly important server-side technology: stored procedures. To get started, let's have a quick look at the difference between entity and value types. It might be useful to refer to my earlier articles on JPA and Hibernate.

Entity and Value Types

In Hibernate, types can be either entity or value. An entity type has a persistent identity, which means it has an independent database life cycle. In other words, entities can be persisted to the database, read from the database, updated, etc. A value type differs from an entity type because it doesn’t have a persistent identity. However, entity and value types often tend to go hand in hand.

A typical entity type is a user—e.g., a system user. The postal address of such a user can be modeled as a value type. It may therefore help to think of a value type as an attribute of an entity. It's no surprise then to realize that an entity may support individual value types as well as collections of value types. A collection of entity types is also possible. Before looking at a collection example, let's review the basic entities in the model under consideration: Person and Department. A department contains zero, one, or more persons (or people).

A Simple Person Entity

This leads into our first code example in Listing 1.

The first entity we’ll look at in Listing 1 is a Person entity class.

Listing 1—A Person Entity

@Entity
@Table(name = "PERSON")
public class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "PERSON_ID")
    private Long id;
    private String lastName;
    private String firstName;
    private String friends;
    
    public Person() {
    }
    public Long getId() {
        return id;
    }
    
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getFriends() {
        return friends;
    }
    public void setFriends(String friends) {
        this.friends = friends;
    }
    @Override
    public String toString() {
        return "Person [id=" + id + ", lastName=" + lastName + ",      firstName="
                + firstName + ", friends=" + friends + "]";
    }
}

In Listing 1, you see a simple mapping of a Person class as indicated by the @Entity annotation. This annotation describes the class as a persistent entity—i.e., an instance of this class will typically reside in a row in the database. The rest of the Person class is just getter and setter methods and a toString() method.

In Listing 2, you see a Department class—a somewhat more complex item than the Person class in Listing 1.

Listing 2—A Department Entity Type with a Collection of Person Entities

@Entity
@Table(name = "DEPARTMENT")
public class Department implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "DEPT_ID")
    private Long id;
    @Column(name = "name", unique=true)
    private String name;
    
    private List<Person> persons = new ArrayList<Person>();
    
    public Department() {
    }
    
    public Department(String name) {
        this.name = name;
    }
    public Long getId() {
        return id;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @OneToMany(cascade=CascadeType.ALL, mappedBy="department")
    public List<Person> getPersons() {
        return persons;
    }
    public void setPersons(List<Person> persons) {
        this.persons = persons;
    }
    
    @Override
    public String toString() {
        return "Department [id=" + id + ", name=" + name + "]";
    }
}

In Listing 2, an important item is illustrated in the following line:

    private List<Person> persons = new ArrayList<Person>();

This line indicates that the Department class contains a collection of Person instances. In fact, Listings 1 and 2 provide an example of what's called a unidirectional one-to-many association. This simply means that one department can contain zero, one, or more persons. The unidirectional aspect of the relationship reflects the fact that Department entities know about the Person instances contained within them, but not vice versa.

Let's see how to use these classes in some simple Java code, as illustrated in Listing 3.

Listing 3—Creating a Department Entity

    public void createDepartment(String departmentName) {
        try {
            // Start EntityManagerFactory
            EntityManagerFactory emf = Persistence
                    .createEntityManagerFactory("punit");
            // First unit of work
            EntityManager entityManager = emf.createEntityManager();
            EntityTransaction entityTransaction = entityManager
                    .getTransaction();
            entityTransaction.begin();
            
            Department department = new Department(departmentName);
            entityManager.persist(department);
            entityTransaction.commit();
            entityManager.close();
            emf.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }       
    }

Don't worry about the details in Listing 3 for the moment. You'll see the whole picture shortly when we look at a full Eclipse project. In Listing 3, I pass in a department name as a Java String, and I then create an instance of the Department class with the following lines:

     Department department = new Department(departmentName);
     entityManager.persist(department);

The code in Listing 3 all boils down to creating an instance of Department by calling entityManager.persist(). This is the magic of object relational mapping.

The code that encloses the previous two lines is required if you run the project outside of a container—e.g., if the code is run in a JavaSE environment. If, on the other hand, you use one of the usual containers—such as, JBoss or Glassfish or WebLogic—then the previous two lines are typically all that is required. In the case where a container such as JBoss is used, then the EntityManager instance is typically injected into the code, thereby simplifying the Listing 3 method. The injection mechanism is referred to as dependency injection, and one of its merits is that the container helps you to simplify your code. The downside to dependency injection is that it imposes a configuration burden, but there's no such thing as free technology!

You've now seen how to persist an instance of Department. What about creating a Person instance in the database? Well, it's a similar story to Listing 3 as illustrated in Listing 4.

Listing 4—Creating a Person Entity

    public void createPerson(Person person) {
        try {
            // Start EntityManagerFactory
            EntityManagerFactory emf = Persistence
                    .createEntityManagerFactory("punit");
            // First unit of work
            EntityManager entityManager = emf.createEntityManager();
            EntityTransaction entityTransaction = entityManager
                    .getTransaction();
            entityTransaction.begin();
            entityManager.persist(person);
            entityTransaction.commit();
            entityManager.close();
            emf.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }       
    }

In Listing 4, I pass in a Person instance, which simplifies the persistence code down to the same boilerplate code as in Listing 3 but with this line added:

            entityManager.persist(person);

Again, if we run the code in a container, then it becomes much simplified!

  • + Share This
  • 🔖 Save To Your Account