Simple Java Persistence API (JPA) Demo

One of the most visible obstacles to effective learning, IMHO, are wizards and various sorts of automation tricks used to simplify life for a developer. Now, before you jump off the edge and narrate a list of the benefits that tools in general provide let me just clarify that I am not against tools but newbies should not be introduced to tools when they are learning to develop software. I tend to think that it takes focus away from the details of the development process. So, I have been playing around with Netbeans 6.0 and I am quite impressed by the new features and amazed by how productive they can make developers. As with all tools, you tend to get used to the way Netbeans does things and soon enough you wouldn’t know how to find your way around a compiler argument.

One of the most interesting features in Netbeans 6.0 is its support for JPA (Disclaimer: that is not a scientific stance … feel free to let me know of any better JPA experiences). While Netbeans 6.0 makes developing CRUD applications easy, I felt like I was learning how the Netbeans team view JPA and I would like to have an appreciation for the technology on its own or at least as far low level as I can go at this point.

I set out to implement a small application without the support of Netbeans or any IDE. A text editor with syntax highlight support would suffice for this task. After starting out with a single class, I discovered that my Java development environment was not setup nicely; I guess, I never got around to customizing it after formatting my hard disk. The process of setting up the environment made me realize that I couldn’t possibly do the demo with a text editor and the compiler alone. I needed a tool to help me with the compilation and of course subsequent execution. Besides, such a tool would also allow the demo to be somewhat portable. I decided to setup Apache Ant. I especially didn’t want to have to add all the jar files that I need for this demo to some environment variable and of course doing that would tie the demo to my machine.

Overview of Object Relational Mapping

The most common and popular method of storing data is in relational database though this by no means means that it is the only way of storing data. Most business application need to interact with a relational database at some point in their running and due to data-centric business operations, the data stored in the relational databases will last longer than most of the applications used to handle it. Object oriented software development has caught on and most of the popular programming languages are either purely (to some extend) OO or are capable of supporting OO concepts. OO is great for application logic and relational databases are great for data storage and manipulation but clearly these two are based on two different paradigms. The definition of a class is not so different from a definition of a table but there are concepts in either of these paradigms that doesn’t neatly map into the other. For example there is no equivalent of OO’s inheritance in the relational paradigm but inheritance can be represented. The mismatch between these two paradigms is usually reference to as the Impedance mismatch.

In order to develop applications, software developers have had to overcome the impedance mismatch and earlier efforts had been tedious since it is upon the developer to retrieve the data from the relational database and then transform it into objects which are then handled by the business logic. When it is time to send the business objects to the database, it is once again necessary to transform the object into a format that makes sense to a relational database. This back and forth movement between the OO and relational paradigms can be automated to some degree by defining an bridge between the two such that this bridge is able to transform back and forth with minimal involvement of the developer.

This is the need that ORM products address and most of them prescribe the definition of the mapping between the OO and relational paradigms; earlier ORM technologies made use of XML to specify the mapping between classes and tables. While the EJB standard require objects to implement interfaces and extend classes in order to benefit from ORM. The EJB approach typically targeted large scale enterprise application which left the small-medium scale application uncovered with regard to persistence though yes you can argue that JDBC was adequate for the needs of the small-medium scale application developers. For the Java community TopLink and Hibernate have been popular ORM products in the commercial and open source space respectively. For the Java community, it became necessary to standardize the persistence technologies that are in use and that’s how the JPA (Java Persistence API) comes into play.

The Idea of the Application

The application in this scenario manages the rooms in a hotel. From outset, the emphasis of the application will be more on the model than its capabilities – after all the objective is to get a hands on experience with JPA. This also mean that any UI enhancements will be added later on (… at least eventually? :)).

The application will enable the user to keep track of hotels; hotels have rooms and rooms have features and characteristics that distinguish them from all others.

Objectives

  • Demonstrate the basic CRUD capabilities of JPA without the use of an IDE
  • Portability across database products supported by JPA
  • The application should be self contained – doesn’t need a large, network based, multi-user RDBMS to implement

The Design

The application will be designed in 3-tiers though for the moment, I am more interested in the database layer and application layer. So, for the database … we will not worry too much about which database we are using because one of the objectives is to have the demo portable across the vendor divide which of course means that we are not going to leverage features specific to a particular database product (not that we need to do that).

The original database was developed on Apache Derby in order to achieve the objective of having the application self contained. Apache Derby can be configured as a network server but in this application it is configured as an embedded database. There are obvious performance implications as a result of using an embedded database but portability in the design should make it easy to switch to the network server installation of Apache Derby or move up to something much larger like MySQL or perhaps even Microsoft SQL Server. While working on the application, I couldn’t have Apache Derby’s tools connected to the database and run the application successfully at the same time. Multiple access to the database was not allowed.

A bit of a background on the database selection process: the original intention was to use SQLite as the database but the JPA implementation distributed with Sun’s GlassFish Application Server does not support SQLite as a database at the time. Other embedded database products considered included HSQL and PointBase and of course Apache Derby.

For the business layer, I have the following objects identified:

    Object Name Description
    Hotel Network operator client
    Room A Hotel room
    Feature A feature
    FeatureGroup Enables features to be group under one category and thus make it easier to ensure sensible feature assignments to rooms e.g. Single bed and double bed are two separate features but both can be assigned to the same room. Putting these features in one category would make it easy for the application to do validations so as to ensure sensible features are chosen for the rooms.
       

The Java Persistence API

From Sun:

The Java Persistence API is a POJO persistence API for object/relational mapping. It contains a full object/relational mapping specification supporting the use of Java language metadata annotations and/or XML descriptors to define the mapping between Java objects and a relational database. It supports a rich, SQL-like query language (which is a significant extension upon EJB QL) for both static and dynamic queries. It also supports the use of pluggable persistence providers.

The JPA is developed as part of EJB 3.0 (JSR-220). EJB is a standard server-side component model implemented in application servers to enable them manage transactions, object distribution, concurrency, security, persistence, and resource management. These capabilities are automatically provided to distributed business applications that run in a compliant application. Included in the list of EJB capabilities is persistence and in EJB 3.0 that is the part of the architecture that is handled by JPA.

Entity

This is a Java class that represents an object in the domain model and as such its state can be persisted to a data store for late retrieval. Java Persistence API does its magic on what is commonly referred to as a Plain Old Java Object or simply POJO. A normal Java class is marked as an entity either through annotations or in an XML mapping descriptor.

Entities support inheritance, polymorphic associations, and polymorphic queries. Both abstract and concrete classes can be entities. Entities may extend non-entity classes as well as entity classes, and non-entity classes may extend entity classes.

The state of an entity is represented by instance variables, which may correspond to Java-Beans properties. The state of the entity is available to clients only through the entity’s accessor methods (getter/setter methods) or other business methods. Instance variables must be private, protected, or package visibility. The mapped state of an entity needs to be accessible to the persistence provider at run time so that the provider can update the database when the state of the entity changes. There are two ways of accessing an entity’s state:

  1. Field Access: annotating the fields of the entity (as shown below) will cause the persistence provider to by-pass the getter and setter methods of the entity class. Notice that the getter/setter methods may or may not be present but they are ultimately ignored by the persistence provider.
  2. Property Access: when this method or mode of access is used the getter/setter methods must be present. The annotations are placed on the getter methods of the entity.

The JPA puts some requirements on a Entity class as follows:

  • The entity class must have a no-arg constructor. The entity class may have other constructors as well.
    The no-arg constructor must be public or protected.
  • The entity class must be a top-level class. An enum or interface should not be designated as an entity.
  • The entity class must not be final. No methods or persistent instance variables of the entity class may be
    final.
  • If an entity instance is to be passed by value as a detached object (e.g., through a remote interface), the
    entity class must implement the Serializable interface.

The Annotations

JPA leverages annotations to implement object relational mapping but it is by no means the only way to achieve mapping. To understand the need for annotations, just consider the number of frameworks and APIs that make use of XML for configuration. It has become complicated to manage the large number of XML that can be found in one JEE project.

JPA specific annotations are colored orange in the above code sample and their simple and brief explanation follows:

Code Sample

package model;

import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Id;
import javax.persistence.Column;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.OneToMany;
import javax.persistence.JoinColumn;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;

import java.util.Date;
import java.util.Collection;

@Entity
@Table(name=”tblHotal”)
/**
* Hotel class
*
* @author Imma
*/
public class Hotel
{
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id;
    @Column private String name;
    @Temporal(TemporalType.TIMESTAMP) private Date dateCreated;
    @OneToMany(mappedBy=”hotel”) private Collection<Room> rooms;

    public Hotel(){}

    public void setId(int id) { this.id = id; }
    public void setName(String name) { this.name = name; }
    public void setRooms(Collection<Room> rooms){ this.rooms = rooms; }
    public void setDateCreated(Date dateCreated) { this.dateCreated = dateCreated; }

    public int getId() { return this.id; }
    public String getName() { return this.name; }
    public Collection<Room> getRooms() { return this.rooms; }
    public Date getDateCreated() { return this.dateCreated; }
}

@Entity: marks an class as an entity. It is normally used to mark classes but can also be used to annotated subclasses and superclasses which may persist to different tables.

@Table: this annotation provides the mapping details between the entity class and the database table to which data about the entity is to be persisted and subsequently retrieved.

@Id: identifies a field of the class as  simple primary key. It can be used in conjunction with the @GeneratedValue annotation for simple primary keys that are automatically generated by the database using an auto increment feature that is common with most RDBMS.

@GeneratedValue: identifies an attribute such as a primary key field that is automatically generated.

@Column: this annotation tag is used to mark the column to which an attribute of an entity is persisted to. By default it takes on the name of the attributes which is being annotated. It can be placed on a field for field access or on a method for property access mode. In the above code sample the entity attribute name is annotated with the @Column annotation tag and since the name of the column is not specified, the JPA runtime assumes that name of the column is the same as the name of the attribute.

@Temporal: used to make a date, time or timestamp field.

@OneToMany: associations between entities can be bidirectional. For example, in the example application: a hotel has many rooms thus many rooms belong to one hotel. In order to fully express this relationship, two mappings are required. The relationship between a hotel and its rooms, with the hotel as the owning entity is marked using the @OneToMany annotation as shown in the code sample above. The inverse of this association is using the @ManyToOne annotation which is described next (after the code sample below).

The Room Class code is shown below; a hotel has many rooms and a room belongs to one and only one hotel. Notice how the relationship/association between the two classes is achieved using annotations and JPA. In addition to this, a room has features and a feature can below to more than one room. Conversely, a room has many features.

package model;

import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Id;
import javax.persistence.Column;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.ManyToOne;
import javax.persistence.ManyToMany;
import javax.persistence.JoinTable;
import javax.persistence.JoinColumn;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;

import java.util.Date;
import java.util.Collection;

@Entity
@Table(name=”tblRoom”)

/**
* Room class
*
* @author Imma
*/

public class Room
{
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id;
    @Column private String number;
    @ManyToOne @JoinColumn(name=”fkHotel”) private Hotel hotel;
    @ManyToMany
    @JoinTable(name=”tblRoomFeatures”, joinColumns=@JoinColumn(name=”fkRoom”),
               inverseJoinColumns=@JoinColumn(name=”fkFeature“))
    private Collection<Feature> features;

    public Room() {}

    public void setId(int id) { this.id = id; }
    public void setNumber(String name) { this.number = number; }
    public void setHotel(Hotel hotel) { this.hotel = hotel; }
    public void setFeatures(Collection<Feature> features) { this.features = features; }

    public int getId() { return this.id; }
    public String getNumber() { return this.number; }
    public Hotel getHotel() { return this.hotel; }
    public Collection<Feature> getFeatures() { return this.features; }

    public String getFeaturesAsString(){
        StringBuilder sb = new StringBuilder();
        sb.append(“{“);
        for(Feature f : features){
            sb.append(f.getName());
            sb.append(“, “);
        }

        if(sb.length() > 2)
        sb.delete(sb.lastIndexOf(“,”), sb.length());
        sb.append(“}”);

        return sb.toString();
    }
}

@ManyToOne: this is an annotation that is used to map a many to one relationship between entities. For example, in the code sample above a Room belongs to a hotel and a hotel has many rooms. I think it is easier to think of it as mapping many rooms to one hotel hence Many-To-One. Depending on how you named your columns in your database, you may need to use an additional annotation to complete the many to one mapping.

@JoinColumn: at the simplest level, this annotation is used to indicate columns in a database table that are involved in a relationship. This relationship could be a many to one as described above or a many-to-many relationship, as described below. In a many-to-one relationship, the @JoinColumn annotation is used to indicate the foreign key in the entity’s table.

@ManyToMany: this annotation is used to mark many-to-many associations between entities. In relational databases, this would involve the use of a joining table and the @JoinTable annotation is used to indicated this joining table as part of the @ManyToMany annotation.

@JoinTable: this annotation is basically used to mark a joining table for a many to many association. The joinColumns attribute of this annotation is used to indicate the columns that related the owning entity (Feature in the example below) to the other side of the relationship (Rooms in the example below). The inverse of the relationship is indicated using the inverseJoinColumns attribute of the @JoinTable annotation as indicated in the code sample below.

package model;

import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Id;
import javax.persistence.Column;
import javax.persistence.ManyToOne;
import javax.persistence.ManyToMany;
import javax.persistence.JoinTable;
import javax.persistence.JoinColumn;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;

import java.util.Date;
import java.util.Collection;

@Entity
@Table(name=”tblFeature”)

/**
* Feature class
*
* @author Imma
*/
public class Feature
{
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id;
    @Column private String name;
    @Column private String description;
    @ManyToOne @JoinColumn(name=”fkFeatureGroup”) private FeatureGroup group;
    @ManyToMany
    @JoinTable
(name=”tblRoomFeatures”, joinColumns=@JoinColumn(name=”fkFeature”),
               inverseJoinColumns=@JoinColumn(name=”fkRoom“))
    private Collection<Room> rooms;

    public Feature() {}

    public void setId(int id) { this.id = id; }
    public void setName(String name) { this.name = name; }
    public void setDescription(String description) { this.description = description; }
    public void setRooms(Collection<Room> rooms) { this.rooms = rooms; }
    public void setGroup(FeatureGroup group) { this.group = group; }

    public int getId() { return this.id; }
    public String getName() { return this.name; }
    public String getDescription() { return this.description; }
    public Collection<Room> getRooms() { return this.rooms; }
    public FeatureGroup getGroup() { return this.group; }
}

This is part one of this demo. Part II will dwell on how JPA comes to life. If you have any comments and questions, please let me know through the comments section of this blog.

Advertisements
  1. #1 by Uden on March 21, 2008 - 4:13 pm

    Hi, starting with JPA i found this demo. The mapping is clear, but i now would like to see it all working.

    Some time has passes since it was published, but i could not find Part II on this site. Has it been/will it be published?

    thanks.

  2. #2 by Ken on August 26, 2008 - 6:48 pm

    Where is the second part?

    Please continue this great work. I real like it.

  3. #3 by thiva on March 10, 2009 - 5:47 am

    Hi,
    I have a question in my mind abt the association, aggregation and composition and the way there were being mapped in JPA. Please help me to understand the above concept mapping in JPA. E.g If we take up both Hotel and Room in the above examples. How can u differentiate the Composition and association?? Is it through the cascade=All??

    In some of the links they have said Embeddable can be used as aggregation, but i am sure it is possible if the entry in the same table and the cardinality is one. but for collection and the other is an another entity??

    – t

  4. #4 by Mo on June 17, 2009 - 3:35 am

    Very simple and informative Demo. Thanks!

  5. #5 by Yadu on October 6, 2009 - 9:54 pm

    Nice demo. can you also post list of dependency jars and a DBUtil class handling all entity manager and factory initialization detail?

  6. #6 by jsa on March 9, 2012 - 6:48 am

    thanks for the sample…btw, can someone demonstrate how to test it on the main

  7. #7 by Binh on May 21, 2012 - 11:59 am

    Excuse me,I needing JPA theory. You can give some JPA technology book . You can send to : mr.quangbinh@gmail.com . Thank !

  8. #8 by spiele spielen on May 11, 2013 - 9:42 pm

    With the time spent in online game communities and multiplayer games,
    players get the opportunity to make new relationships and strengthen
    the existing ones. When it comes to optimizing
    your game playing, you will be able to get plenty of game
    add-ons with your gold card status. In the game, players should
    be able to able to make use of a slingshot in order
    to start the birds.

  9. #9 by Clicking Here on May 12, 2013 - 6:48 pm

    Whilst you could get a partner or close friend to give
    your shoulders, back or feet a good rub down, to
    truly feel long-term benefits you should enlist the services of a trained professional to
    give you regular massages. What we can do is to really accept what we did while forgiving that part
    of us that was unaware of what we were doing or how it would impact other people; the part that just doesn’t always get it right. I would recommend having a Mimosa out on the patio overlooking the waterway.

  10. #10 by online Radio on May 13, 2013 - 3:18 pm

    The Squeezbox Boom radio from Logitech is not just an Internet radio.
    In my case I listen to all music that is submitted to me
    before I include it on my playlist. Kevin Smith is a stand up comedian known for directing feature film comedies like Clerks,
    Dogma and Jersey Girl.

  11. #11 by Bernardo on May 13, 2013 - 3:33 pm

    You have to give a tube radio at least 20 to 30 minutes just to warm
    up and then you decide what frequency you want to be
    on and load the plate and tune them up. And once you have
    your own project that you want to promote, you must have considered the radio as one of the best
    alternatives to introduce your music to the crowds.
    But mostly BBC Radios 4 and 5 because, being speech orientated, they’re more like what I do, so I can learn lots from them.

  12. #12 by Rapid Methods In schwimmer Revealed on May 14, 2013 - 8:07 am

    Or, I’ve already hit bottom and I’ve nowhere to go but up.
    is a very popular one and there are countless articles and products available to make your life
    easier when it comes to squeezing juice out of this wondrous plant.
    Schwimmer and English part-time photographer
    Zoe began dating then and married in a private ceremony last June after announcing their engagement in March 2010.

  13. #13 by Blake on May 14, 2013 - 12:47 pm

    Major follows some sports, primarily during the playoffs.

    Caution: when a hole is made in a can, there may be metallic edges that can cut one’s mouth. The tables used for this unique drinking game can in fact be purchased commercially.

  14. #14 by http://www.ibook21.com/blog/167749/ on May 14, 2013 - 2:52 pm

    This connectivity will allow you to easily transfer photos
    on to your laptop for storage. 1MP resolution and you can be sure of high quality photos
    with it. There are more important things to consider when deciding if you will pay
    more for a camera.

  15. #15 by radio aktiv varaždin on May 15, 2013 - 9:44 am

    Funny Or Die separates itself from other funny video clip hosting sites by the way it
    lets people rank the videos, get enough
    funny votes and the video will be immortalized get enough
    die votes and the video will be sent into the “crypt”.
    There are hundreds of people working in foreign aid missions, expats, Peace Corps, and others
    in relief and business sectors. This powerful and versatile solution is also available in three different
    versions, so you should have no trouble finding the perfect one
    for you.

  16. #16 by kostenlos spielen on May 18, 2013 - 7:01 pm

    In most cases they are, but when it comes to updates, patches, etc
    to the mmorpgs. This way you are not disappointed when you get residence, and you won’t have to make a excursion back to the shop. It is recommended that the golfers select those putters with which the golfers feel good and works well with their gaming pattern.

  17. #17 by Horace on May 27, 2013 - 1:13 pm

    The pc 2007 elite TV software is therefore legitimate software with over
    3000 TV channels. As an Internet broadcaster, it is high time that you
    pick on these available opportunities and add that $ilver sheen to your broadcasting happiness.

    You can see if any of your Facebook friends are listening by clicking on the Facebook link on the bottom right.

  18. #18 by Winifred on June 10, 2013 - 2:07 am

    You don’t have to hit the gym for two and three hours each day to lose weight, but it does help to squeeze in 30 minutes of physical activity each day. Vinson had participants keep their normal diet and exercise routines (or lack thereof) and merely added the green coffee. Do not be tempted to lose weight as quickly as you can, because a crash diet will have you eating less than a thousand calories a day slowing down your metabolism.

  19. #19 by Dustin on July 27, 2013 - 10:47 am

    Both drugs have also been denied FDA approval the first time around and
    are awaiting news on their second attempt. Vinson had participants keep their
    normal diet and exercise routines (or lack
    thereof) and merely added the green coffee. The institution has persistently offered ideal programs and services for those struggling to achieve certain levels of body weight.

  20. #20 by Luke on July 30, 2013 - 2:11 am

    If you find it a bit maddening to follow the daily fluctuations
    of the scale even though you are eating properly, pick three days of the
    week on which you will always weigh yourself (for example,
    Monday, Wednesday, and Friday). Avocados- Although not my favorite, are high in fats, the good ones.
    That way, the actual process will end up being much
    less frustrating and, for the majority of people, enjoyable.

  21. #21 by Charis on August 6, 2013 - 2:52 am

    It does appear, however, that hypnosis can help a person achieve his or
    her weight loss goals. Authorities inside the area will need
    to have an intensive understanding of laboratory and labeling
    techniques, infection security precautions, appropriate blood attract approaches to the elderly and for infants
    and even more. Many people don’t have the time to weight themselves every day, but checking the scale on a regular basis can definitely help when you’re working
    to lose weight and keep it off.

  22. #22 by http://www.auraque.com/index.php/member/7484/ on August 6, 2013 - 11:38 am

    It does appear, however, that hypnosis can help a person achieve his or her weight loss goals.
    Cucumber contains sterols which can help to lower cholesterol and prevent carbohydrates from converting to body fat.
    When you’re about to start on your weight loss plan, it’s a good idea to think about your end goal and chunk it down into smaller goals.

  23. #23 by Máy đo đường huyết giá rẻ on August 2, 2014 - 9:35 am

    Nice tutorial. Thanks so much !

  1. Simple Java Persistence API (JPA) Demo: JPA Query « imma

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: