Hibernate Made Easy
Simplified Data Persistence with Hibernate & JPA Annotations
Suggested Retail Price:   $54.98
Current Amazon Purchase Price:   $54.98
When you buy through us on Amazon:   $45.98
You won't find a better price!
Buy through us...Help support the site.
Most Popular Videos
'Cuz some people don't like reading...
Hibernate JPA Video CBT Tutorials Setting up the environment  Setting Up Hibernate
Hibernate and RSA IRAD Rational Software Architect Application Developer CBT Tutorial  Hibernate & Rational (IRAD)
Hibernate JPA Training  Many to Many Associations
Java Persistence With Hibernate Tutorials  Inheritance Mapping
Working with Compund Primary Keys  Compound Primary Keys
Hibernate and Eclipse Tools CBT Tutorial  Using Hibernate & Eclipse
Portlet Programming
Do you Portal? Then you need this...
WebSphere: What is WebSphere? Java J2EE JEE Portal and Beyond

I Even Made Portlets Real Easy :)
Please Spread the Word!
Why keep HiberBook a secret???







If you found this site helpful, please tell other people about it. I'd really, really appreciate it.

SCJA Java Study Guide
Written with your success in mind...
WebSphere: What is WebSphere? Java J2EE JEE Portal and Beyond

Get Java Certified by Sun
Is Google Clairvoyant?
Google thinks you'll like this...
What is WebSphere?
I wrote this... I know you'll love it...
WebSphere: What is WebSphere? Java J2EE JEE Portal and Beyond

Buy it now!
Most Popular Purchases
What people are buying from us...
Popular Hibernate Purchases  Hibernate Made Easy
Popular Hibernate JPA Books  Harnessing Hibernate
The Best Spring and Hibernate Books  Java Persistence w Hibernate
Java Persistence API Books  Spring in Action
Popular Spring and JBoss Books  What is WebSphere?
Popular Spring and JBoss Books  JSR168 Portlet Programming
The SCJA Exam Questions
I wrote this, too. A Great Exam Prep...
WebSphere: What is WebSphere? Java J2EE JEE Portal and Beyond

Get Sun Java Certified
Most Popular Tutorials
High hit reads on this site...
Hibernate and JPA Links  How Hibernate Works
Hibernate and JPA Free Tutorials  Recommended Books
Hibernate and JPA Simple Examples  Coding Advanced DAOs
Hibernate and JPA Free CBTs  Using The Criteria API
Hibernate and JPA Simple Examples  What is Hibernate?
down caret hibernate jpaAre you Harnessing It?
One of the three books you need...
Harnessing Hibernate Book by James Elliott (Author), Tim O'Brien (Author), Ryan Fowler (Author)
Read My Review
Win Yourself $100!!!
The 100% Error Free Code Challenge...

The $100 Code Challenge - No Code Errors, Guaranteed!!!
Learn How to Win a Benjamin

HardCore Hibernate
Yeah, you need this book, too...
Hibernate and JPA Simple Examples

If my book makes it Easy, this book makes Hibernate Hardcore. This is the reference standard...You need it.

Read My Review
Friendly Links
Websites we like...
Hibernate and JPA Links  JavaRanch: Big Moose Saloon
Hibernate and JPA Free Tutorials  Apache.org
Hibernate and JPA Free CBTs  Pickering is Springfield
Hibernate and JPA Simple Examples  Hibernate.org
Hibernate and JPA Simple Examples  mysql.org
Hibernate and JPA Simple Examples  Coast to Coast
Hibernate and JPA Simple Examples  What is IBM WebSphere?
Hibernate and JPA Simple Examples  Desktop Tower Defense
Is Amazon Psychic?
Amazon thinks you'll like this...

My Other Books & Stuff
Other decent books of mine :)...
Sun Certified Java Associate SCJA Study Guide  Java Associate Study Guide
SCJA Mock Exam Questions  SCJA Questions Guide
JSR-168 Portlet Development Book  JSR168 Portlet Programming
WebSphere Introduction and Support Book  What is WebSphere?
The Simpsons is based on Pickering Ontario  Pickering is Springfield
Oshawa Ontario, Discerning Bombs A book about like in Oshawa Ontario  Discerning Bombs on Oshawa
A Good Book on Hibernate and JPA the Java Persistence API  Hibernate Made Easy
From Amazon with Love
Check this stuff out...
Please Spread the Word!
Why keep HiberBook a secret???







If you found this site helpful, please tell other people about it. I'd really, really appreciate it.

More Google Stuff...
Links to entertain you...
Most Popular Purchases
What people are buying from us...
Popular Hibernate Purchases  Hibernate Made Easy
Popular Hibernate JPA Books  Harnessing Hibernate
The Best Spring and Hibernate Books  Java Persistence w Hibernate
Java Persistence API Books  Spring in Action
Popular Spring and JBoss Books  What is WebSphere?
Popular Spring and JBoss Books  JSR168 Portlet Programming
Mapping One-To-Many Associations with Hibernate and JPA Annotations
A simple tutorial showing you how to map your one to many association between classes to the database...

Of all the mappings you're going to see in a Java application, a one to many mapping has to be the most common. Just think about it, an Order has many LineItems; a Bank has many BankAccounts; a Record has many Songs; an Exam has many Questions. The one to many association really has to be the most common multiplicity we see in our Java apps.

For this tutorial, I'm going to model the idea that a Team has many Players. So, given a team, you will be able to obtain a List of the Players that are associated with that team. Furthermore, given a player, you can find out with which team that Player is associated. I guess you could say that it's a bi-directional relationship, as the Player is navigable through the Team object, and the Team is navigable through the Player.

A Team Has Many Players

Since both the Team and Player objects will map to their own, individual, database tables, both the Team and Player classes will have their own primary key to keep track of a record's uniqueness. In both classes, we will maintain the primary key field using a primitive of type long which will be uncreatively named id.

As far as the interesting properties of the Team class goes, well, every team has a name of type String. So, a team might be named the "Soo Greyhounds," or the "Pickering Atoms." As far as the Player class goes, every player has a nickName of type String, so "Lefty" and "Pork Chop" might play for the Pickering Atoms.

Phase 1 of the Player Class (No Association Yet)

package com.examscam.mappings;
public class Player {

 private long id;
 private String nickName;


 public long getId() {return id;}
 public void setId(long id) {this.id = id;}
 public String getNickName() {return nickName;}
 public void setNickName(String n) {this.nickName = n;}
}

Phase 1 of the Team Class (No Association Yet)

package com.examscam.mappings;
public class Team {

 private long id;
 private String name;

 public long getId() {return id;}
 public void setId(long id) {this.id = id;}
 public String getName() {return name;}
 public void setName(String name) {this.name = name;}
}

Coding an Association in Java

Phase 1 of the Team and the Player classes define the basic properties of each object, without doing anything to imply the relationship between the two. Of course, the association between the two is the fact that a Player is associated with a Team, and a Team is associated with many Players. These relationships will be expressed in our Java code through instance variables.

To express the fact that a Player is associated with a Team, we need to add an instance variable of type Team in the Player class.

Phase 2 of the Player Class (Java Associations)

package com.examscam.mappings;
public class Player {
 private long id;private String nickName;

 private Team team;      /* A Player is on a Team */
 public Team getTeam() {return team;}
 public void setTeam(Team t) {this.team = t;}

 public long getId() {return id;}
 public void setId(long id) {this.id = id;}
 public String getNickName() {return nickName;}
 public void setNickName(String n) {this.nickName = n;}
}

Phase 2 of the Team Class (Java Associations)

To express the fact that a Team has many players, we add a variable of type java.util.List, named players, to the Team class.

package com.examscam.mappings;
import java.util.List;
public class Team {
 private long id;private String name;

 private List<Player> players; /*A Team Has Players*/
 public List<Player> getPlayers() {return players;}
 public void setPlayers(List<Player> p){players=p;}

 public long getId() {return id;}
 public void setId(long id) {this.id = id;}
 public String getName() {return name;}
 public void setName(String name) {this.name = name;}
}

Adding the Standard Hibernate Annotations

Of course, instance variables only describe an association between classes at a Java bytecode level. Simply adding instance variables in your Java classes doesn't give Hibernate any information about how to manage the associations. To have Hibernate persist and manage any associations between classes, those Java classes need to be annotated.

Both the Team and the player classes need the standard JPA annotations that describe the fact that they are to be Hibernate managed entities. We also need annotations that describe the fact that the id field will be the primary key whose values will be auto-generated by the database. That means adding the @Entity, @Id and @GeneratedValue JPA tags at the appropriate places in the Player and Team classes.

Phase 3 of the Player Class (Basic Annotations)

package com.examscam.mappings; 
import javax.persistence.*;
@Entity
public class Player {
 private long id;
 private String nickName;

 private Team team;      
 public Team getTeam() {return team;}
 public void setTeam(Team t) {this.team = t;}

 @Id
 @GeneratedValue
 public long getId() {return id;}
 public void setId(long id) {this.id = id;}
 public String getNickName() {return nickName;}
 public void setNickName(String n) {nickName = n;}
}

Phase 3 of the Team Class (Basic Annotations)

package com.examscam.mappings;
import java.util.List; 
import javax.persistence.*;
@Entity
public class Team {
 private long id;
 private String name;

 private List<Player> players; 
 public List<Player> getPlayers() {return players;}
 public void setPlayers(List<Player> p){players=p;}

 @Id
 @GeneratedValue
 public long getId() {return id;}
 public void setId(long id) {this.id = id;}
 public String getName() {return name;}
 public void setName(String name) {this.name = name;}
}

@OneToMany and @ManyToOne Annotations

After the basic JPA annotations identifying the Team and Player classes as managed entities have been added, along with the annotations to decorate the id fields of the two classes, it's time to add the @OneToMany and @ManyToOne JPA annotations. These annotations help Hibernate understand the purpose of the instance variables that implement the Java based associations between the Team and Player classes.

Let's first concentrate on the Player class that maintains a single instance variable of type Team to help identify the team with which a player is associated.

Since many players can be associated with a single team, the relationship is many-to-one, and as such, the getTeam() method in the Player class gets decorated with the @ManyToOne annotation.

Now, it is the responsibility of each Player to keep track of the single Team with which they are associated. In Java, this is achieved through an instance variable, but databases don't have instance variables. Instead, databases use foreign keys in much the same way a Java program uses an instance variable. For a database, each row on the many side of a one to many relationship must maintain a foreign key that maps the row back to the associated row on the many side of the relationship.

So, each row in the Player table must define a column to map the Player back to the associated team. We'll call that column, which will be defined in the player table, team_id.

It is worth mentioning that while the many side in a one to many relationship must define a field that maps back to the encapsulating one side, the reverse is not true. With the player and team tables, the player table (the many table) uses the team_id column to map back to the team table (the one table), but no column is needed in the team table to map to the player.

@JoinColumn and @ManyToOne Annotations

When using JPA annotations to map the many side of a relationship to the encapsulating one side, we not only use the @ManyToOne annotation, but we further decorate the class with the @JoinColumn annotation.

Again, the player database table must define a column to map rows back to the encapsulating team table, and this fact manifests itself through the name attribute of the very important @JoinColumn annotation. These decorations will appear immediately before the getTeam() method of the Player class:

@Entity
public class Player {     
  @ManyToOne
  @JoinColumn(name="team_id")
  public Team getTeam() {return team;}     
}

Of Databases and Java Programs

So, from the perspective of a Java program, the only thing that is needed to express a relationship between classes is the existence of an instance variable; but since databases don't quite work the same way, we need to inform the Hibernate framework as to how it should manage the association at the database layer. This is where the @OneToMany and @JoinColumn JPA annotations come in.

@OneToMany JPA Annotation

The getTeam() method in the Player class was decorated with the @ManyToOne JPA annotation, so it'll probably come as no surprise to find out that the Team side of this bi-directional relationship requires a @OneToMany annotation decorating the getPlayers() method.

public class Team {   
@OneToMany(mappedBy="team", 
             targetEntity=Player.class, 
              fetch=FetchType.EAGER,
               cascade=CascadeType.ALL)
public List<Player> getPlayers() {return players;}  
}

The @OneToMany annotation has a few important attributes that need to be included. First of all, you need to have the mappedBy attribute. And what is the mappedBy attribute? Well, this actually maps to the variable name the encapsulating class(Team) takes in the encapsulated entity Player). So, if you looked at the Player class, you'd see that there is an instance variable of type Team named team, in all lower case letters. This variable named team maps the Player back to their Team, and as such, becomes the value of the mappedBy attribute.

public class Player {
  private long id;
  private String nickName;

/* The Player class has an instance variable named team */

private Team team;    
}

Along with the mappedBy attribute, the @OneToMany annotations needs a targetEntity attribute. Since any generic Object can be placed into a List, Vector, or other collection class that implements the many part of the association, it is important to explicitly state in the annotation what type of object class will be contained in the collection. This should be done even when the contained object type is defined using generics syntax. Since our team contains players, Player.class is the value of the targetEntity attribute of the Team's @OneToMany annotation.

Final Phase of the Player Class

package com.examscam.mappings;
import javax.persistence.*;
@Entity
public class Player { 
 private long id;
 private String nickName;
 private Team team;

 @ManyToOne
 @JoinColumn(name="team_id")      
 public Team getTeam() {return team;}
 public void setTeam(Team t) {this.team = t;}
 @Id
 @GeneratedValue
 public long getId() {return id;}
 public void setId(long id) {this.id = id;}
 public String getNickName() {return nickName;}
 public void setNickName(String n) {nickName = n;}
}

Final Phase of the Team Class

package com.examscam.mappings;
import java.util.List; import javax.persistence.*;
@Entity
public class Team {
 private long id; 
 private String name;
 private List<Player> players; 

 @OneToMany(mappedBy="team",  
              targetEntity=Player.class, 
    fetch=FetchType.EAGER, cascade = CascadeType.ALL)
 public List<Player> getPlayers() {return players;}
 public void setPlayers(List<Player> p){players=p;}
 @Id
 @GeneratedValue
 public long getId() {return id;}
 public void setId(long id) {this.id = id;}
 public String getName() {return name;}
 public void setName(String name) {this.name = name;}
}
 

FetchType and CascadeType Revisited

Notice that the @OneToMany annotation uses the fetch and cascade attributes. While optional, it is always important to think about the potential negative impact of doing an eager fetch on associated classes. If loading associated classes will have a negative impact on performance, you might want to leave the fetch type to the default value of LAZY. Just be sure that with a lazy fetch setting that you don't try and access associated classes outside of a transaction, as you will ended up getting a blank proxy, not the actual data, resulting in a very frustrating and often perplexing LazyInitialization runtime exception.

Furthermore, it is important to think about how saves to a containing object, such as Team, will effect the contained objects, in this case, the Players. If you want changes to the owning entity to cascade to the owned entity when a change occurs, you should set your CascadeType to ALL. Other available options for the CascadeType include: MERGE, PERSIST, REFRESH and REMOVE.

Testing the Implementation

Let's test our one-to-many JPA annotated classes:

To test the @OneToMany and @ManyToOne mappings, you must first add both the Team and Player classes to the Hibernate configuration.

AnnotationConfiguration config = new AnnotationConfiguration();
config.addAnnotatedClass(Player.class);
config.addAnnotatedClass(Team.class);
config.configure();

After making sure the Player and Team classes are added to the configuration, you must make sure the corresponding tables actually exist in the database. I like to get Hibernate to do this for me by using my HibernateUtil.recreateDatabase() method, but you can also do it by running the following SQL script:

CREATE TABLE  'examscam'.'player' 
('id' bigint(20) NOT NULL auto_increment, 
'nickName' varchar(255) default NULL, 
'team_id' bigint(20) default NULL, 
PRIMARY KEY  ('id'), 
KEY 'FK8EA387017289A91D' ('team_id'));

 
CREATE TABLE  'examscam'.'team'
 ( 'id' bigint(20) NOT NULL auto_increment, 
 'name' varchar(255) default NULL, 
 PRIMARY KEY  ('id'));

Testing the Team and Players

Because both the Team and Player classes are marked with the @Entity tags, any time a Team or Player class is created, it is a good practice to have the entity touch the Hibernate Session for its persistence to be managed.

Session session = HibernateUtil.beginTransaction();
Team team = new Team();
Player p1 = new Player();
Player p2 = new Player();
session.save(team);
session.save(p1);
session.save(p2);

After 'touching' the Hibernate Session, any subsequent changes, updates or associations that are made to the entity are managed by Hibernate and persisted to the database.

team.setName("Pickering Atoms");
p1.setNickName("Lefty");
p1.setTeam(team);
p2.setNickName("Blinky");
p2.setTeam(team);
HibernateUtil.commitTransaction();

After committing the transaction to the database, there are two players, Lefty and Blinky, who are both associated with the Pickering Atoms, giving them both a team_id of 1.

Full Team Class with the Testable main

package com.examscam.mappings;
import java.util.*; import javax.persistence.*;
import org.hibernate.Session; import com.examscam.HibernateUtil;
@Entity
public class Team {
 private long id; 
 private String name;
 private List<Player> players; 

 @OneToMany(mappedBy="team",  
              targetEntity=Player.class, 
    fetch=FetchType.EAGER, cascade = CascadeType.ALL)
 public List<Player> getPlayers() {return players;}
 public void setPlayers(List<Player> p){players=p;}
 @Id
 @GeneratedValue
 public long getId() {return id;}
 public void setId(long id) {this.id = id;}
 public String getName() {return name;}
 public void setName(String name) {this.name = name;}
}
 public static void main(String args[]){
    HibernateUtil.recreateDatabase();
    Session session=HibernateUtil.beginTransaction();

    Team team = new Team();
    Player p1 = new Player();
    Player p2 = new Player();

    session.save(team);
    session.save(p1);
    session.save(p2);

    team.setName("Pickering Atoms");
    p1.setNickName("Lefty");
    p1.setTeam(team);
    p2.setNickName("Blinky");
    p2.setTeam(team);
    HibernateUtil.commitTransaction();
  }
}

Hibernate and SQL Execution

When committing the transaction to the database, Hibernate logs the following very interesting SQL statements, reflecting the flow of object creation and updates to the instance variables of the Player and Team classes as the code progresses.

Session session = HibernateUtil.beginTransaction();
Team team = new Team();
Player p1 = new Player();
Player p2 = new Player();
session.save(team);
session.save(p1);
session.save(p2);
team.setName("Pickering Atoms");
p1.setNickName("Lefty");
p1.setTeam(team);
p2.setNickName("Blinky");
p2.setTeam(team);
HibernateUtil.commitTransaction();


H: insert into Team (name) values (?)
H: insert into Player (nickName, team_id) values (?, ?)
H: insert into Player (nickName, team_id) values (?, ?)
H: update Team set name=? where id=?
H: update Player set nickName=?, team_id=? where id=?
H: update Player set nickName=?, team_id=? where id=?

Looking at the results in the database, you can see that Lefty and Blinky are both players on the Pickering Atoms team. The single Team, the Pickering Atoms, has many players, namely Lefty and Blinky - making this a one to many, and inversely, a many to one, relationship mapping.


hibernate java hibernate spring hibernate hibernate cache hibernate class hibernate collection hibernate configuration hibernate database hibernate dialect hibernate download hibernate example hibernate mapping hibernate query hibernate sql hibernate tutorial hibernate xml struts hibernate xp hibernate 3 hibernate 3.0 hibernate api hibernate caching hibernate cfg xml hibernate dao hibernate examples hibernate framework hibernate generator hibernate in action hibernate jdbc hibernate list hibernate one to one hibernate plugin hibernate properties hibernate tool hibernate tools hibernate training hibernate tutorials java persistence with hibernate jboss hibernate linux hibernate standby hibernate ubuntu hibernate xdoclet hibernate hibernate synchronizer computer hibernate disable hibernate enable hibernate hibernate 2 hibernate 3.2 hibernate annotation hibernate annotations hibernate bag hibernate batch hibernate blob hibernate button hibernate c3p0 hibernate cascade hibernate command hibernate composite id hibernate composite key hibernate config hibernate connection hibernate criteria hibernate date hibernate delete hibernate discriminator hibernate documentation hibernate ehcache hibernate entitymanager hibernate enum hibernate fetch hibernate file hibernate filter hibernate flush hibernate formula hibernate forum hibernate hbm hibernate hbm2ddl hibernate hbm2ddl auto hibernate hql hibernate id hibernate in vista hibernate inheritance hibernate insert hibernate interceptor hibernate interview questions hibernate inverse hibernate javadoc hibernate join hibernate jpa hibernate lazy hibernate lazy loading hibernate load hibernate logging hibernate many to many hibernate many to one hibernate map hibernate mapping file hibernate merge hibernate mode hibernate named query hibernate order hibernate order by hibernate org hibernate performance hibernate problems hibernate property hibernate proxy hibernate query language hibernate reference hibernate restrictions hibernate reverse engineering hibernate save hibernate saveorupdate hibernate search hibernate select hibernate sequence hibernate session hibernate sessionfactory hibernate set hibernate shortcut hibernate show_sql hibernate source hibernate sql query hibernate stored procedure hibernate template hibernate timestamp hibernate transaction hibernate type hibernate update hibernate usertype hibernate validator hibernate version how to hibernate laptop hibernate net sf hibernate netbeans hibernate org hibernate dialect org hibernate session sleep hibernate sleep vs hibernate spring and hibernate standby vs hibernate turn off hibernate vista hibernate what is hibernate windows hibernate windows xp hibernate all 150 Help java spring apache xml ajax cache cmp j2ee s truts tomcat ejb jboss jsf maven primary key ruby on rails foreign key hibernation ibatis one to one spring framework xdoclet hql hybernate jdo many to many middlegen ojb one to many

eXTReMe Tracker