14 - Association Mapping in Hebernate: Page 2 of 4

14.3 One to Many Association

One to Many association is the other side of Many to One association. Many Cricket Matches can be played in one stadium, is an example of many to one association from Cricket matches end. On the other side One stadium can host many cricket matches is the one to many association from Stadium end.

Hibernate provides <one-to-many> tag to support this association. On the Application side, we can use any collection like Set, List, Map etc., which we discussed in the earlier chapter.

You must be wondering that we discussed a similar concept in Chapter 13 also. So the Answer is yes, we did, but there is a difference. Collections we discussed in the previous chapter were of value type (they don’t exist with their own) but here the collections are entity and they do have their own lifecycle. Due to this change we will use <one-to-many> tag instead of <composite-element> tag

From a database design perspective, association is implemented by having a column in table representing “many” part of the relationship to hold the primary key of another table. This way this column is a foreign key.

In our example, Cricket_Match table will have an extra column to hold the stadium_ids 

Let’s design our Entity classes.

CricketMatch.java

package com.tutorial.hibernate;

public class CricketMatch {

      private int id;    
      private String team1;    
      private String team2;    
      private String umpire;    
      private String type;

      public int getId() {
        return id;
      }
      public void setId(int id) {
        this.id = id;
      }
      public String getTeam1() {
        return team1;
      }
      public void setTeam1(String team1) {
        this.team1 = team1;
      }
      public String getTeam2() {
        return team2;
      }
      public void setTeam2(String team2) {
        this.team2 = team2;
      }
      public String getUmpire() {
        return umpire;
      }
      public void setUmpire(String umpire) {
        this.umpire = umpire;
      }
      public String getType() {
        return type;
      }
      public void setType(String type) {
        this.type = type;
      }    
      @Override
      public String toString() {
        return "CricketMatch [id=" + id + ", team1=" + team1 + ", team2="
                + team2 + ", umpire=" + umpire + ", type=" + type
                +  "]";
      }    
}

Stadium.java

package com.tutorial.hibernate;

import java.util.HashSet;
import java.util.Set;

public  class Stadium {

    private int id;        
    private String name;
    private String country;    
    private int capacity;

    private Set<CricketMatch> matches= new HashSet<CricketMatch>();

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getCountry() {
        return country;
    }
    public void setCountry(String country) {
        this.country = country;
    }
    public int getCapacity() {
        return capacity;
    }
    public void setCapacity(int capacity) {
        this.capacity = capacity;
    }    
    public Set<CricketMatch> getMatches() {
        return matches;
    }
    public void setMatches(Set<CricketMatch> matches) {
        this.matches = matches;
    }
    @Override
    public String toString() {
        return "Stadium [id=" + id + ", name=" + name + ", country=" + country
                + ", capacity=" + capacity + "]";
    }                
}

association-mapping.hbm.xml -<one-to-many> tag  is used in Stadium Match  mapping and its column attribute specifies the column name to hold the stadium ids. At the application end, we need not to define additional property corresponding to this column., hibernate does manage it internally.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
 "-//Hibernate/Hibernate Mapping DTD//EN"
 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


<hibernate-mapping>
    <class name="com.tutorial.hibernate.CricketMatch" table="Cricket_Match">
        <id name="id" type="int" column="match_id">
            <generator class="native" />
        </id>

            <property name="team1" column="team1" type="string" />
            <property name="team2" column="team2" type="string" />
            <property name="type" column="type" type="string" />    
            <property name="umpire" column="umpire" type="string" />
     </class>

     <class name="com.tutorial.hibernate.Stadium" table="Stadium">
        <id name="id" type="int" column="stadium_id">
            <generator class="native" />
        </id>
        <property name="name" type="string" column="stadium_name" />
        <property name="capacity" type="int" column="capacity" />
        <property name="country" type="string" column="country" />

        <set name="matches" >
            <key column="stadium_id"></key>
            <one-to-many class="com.tutorial.hibernate.CricketMatch" />
        </set>
     </class>
</hibernate-mapping>

Create Table Scripts

CREATE TABLE 'stadium' (
  'stadium_id' int(11) NOT NULL AUTO_INCREMENT,
  'stadium_name' varchar(255) DEFAULT NULL,
  'capacity' int(11) DEFAULT NULL,
  'country' varchar(255) DEFAULT NULL,
  PRIMARY KEY ('stadium_id')
); 

CREATE TABLE 'cricket_match' (
  'match_id' int(11) NOT NULL AUTO_INCREMENT,
  'team1' varchar(255) DEFAULT NULL,
  'team2' varchar(255) DEFAULT NULL,
  'type' varchar(255) DEFAULT NULL,
  'umpire' varchar(255) DEFAULT NULL,
  'stadium_id' int(11) DEFAULT NULL,
  PRIMARY KEY ('match_id'),
  KEY 'FK' ('stadium_id'),
  CONSTRAINT 'FK_70fxuvas8xraq7mo6rpmsekxx' FOREIGN KEY ('stadium_id') REFERENCES 'stadium' ('stadium_id')
);

Test Program – Below is the test program to insert and retrieve the data.  

import java.util.HashSet;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.tutorial.hibernate.CricketMatch;
import com.tutorial.hibernate.Stadium;

public class Test {
 
       private static SessionFactory factory;  

       public static void main(String args[])
       {

         Configuration cfg = new Configuration().configure();
         factory = cfg.buildSessionFactory();        
         Session session = factory.openSession();
         Transaction tx = session.beginTransaction();
       
         Stadium stadium = new Stadium();

         stadium.setCapacity(2300);
         stadium.setCountry("Australia");
         stadium.setName("Sydney");

         CricketMatch match1 = new CricketMatch();

         match1.setTeam1("India");
         match1.setTeam2("Australia");
         match1.setType("Test Match");
         match1.setUmpire("Billy Bowden");
        
         CricketMatch match2 = new CricketMatch();

         match2.setTeam1("West Indies");
         match2.setTeam2("South Africa");
         match2.setType("T 20");
         match2.setUmpire("Stuart Willy");

         Set<CricketMatch> matches = new HashSet<CricketMatch>();
        
         matches.add(match1);
         matches.add(match2);

         stadium.setMatches(matches);
         session.save(match1);
         session.save(match2);

         int stadiumId= (Integer)session.save(stadium);

         tx.commit();
         session.close();

         getStadiumDetails(stadiumId);        
         factory.close();        
    }

    private static void getStadiumDetails(int id)
    {

        Session session = factory.openSession();        
        Stadium stadium = (Stadium)session.get(Stadium.class,id);        
        Set<CricketMatch> matches  = stadium.getMatches();

        System.out.println(matches);
        System.out.println(stadium);
    }
}

Test Program – Below is the test program to insert and retrieve the data.  

Stadium Table

 

Cricket_Match Table

 

Like us on Facebook