15 - Hibernate Cascade and Fetching Strategy

15.1 Overview

In the previous chapter, we discussed persistence of parent and child relations and we did highlight the point of additional code, that has been written to save the child object. However the parent class should handle it internally. In this chapter, we will discuss the cascading the object state and different fetching strategies that can be used to improve the performance.

15.2 Cascading Object State

The whole concept of parent child relationship is that one object should take care of persistence of another object internally and application programmer need not write additional code to manage the persistence. In chapter 14 we saw that we need to explicitly call save operation on both stadium and on cricketmatch like below 

Stadium stadium = new Stadium();

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

CricketMatch match = new CricketMatch();
match.setTeam1("India");
match.setTeam2("Australia");
match.setType("Test Match");
match.setUmpire("Billy Bowden");
match.setStadium(stadium);

session.save(stadium);
session.save(match);

Hibernate provides an option “cascade” which offers several options to handle such scenarios.

We will use below hibernate.cfg.xml in this entire chapter

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

       <property name="hibernate.connection.url">
            jdbc:mysql://localhost:3306/tutorial
        </property>
        <property name="hibernate.connection.username">
            root
        </property>
        <property name="hibernate.connection.password">
            password
        </property>
        <property name="dialect">  
            org.hibernate.dialect.MySQLDialect
        </property>

        <property name="hibernate.format_sql">true</property>        
        <property name="show_sql">true</property>
        
        <property name="hibernate.connection.driver_class">
            com.mysql.jdbc.Driver
        </property>
        <mapping resource="association-mapping.hbm.xml" />
    </session-factory>
</hibernate-configuration> 

15.2.1 Scenario

We will take a scenario of  One to Many association  between Stadium and Cricket Match. One stadium can host many cricket matches is the one to many association from Stadium end.

 Let’s design our Entity classes which we will use in the entire chapter

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 int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + id;
        result = prime * result + ((team1 == null) ? 0 : team1.hashCode());
        result = prime * result + ((team2 == null) ? 0 : team2.hashCode());
        result = prime * result + ((type == null) ? 0 : type.hashCode());
        result = prime * result + ((umpire == null) ? 0 : umpire.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        CricketMatch other = (CricketMatch) obj;
        if (id != other.id)
            return false;
        if (team1 == null) {
            if (other.team1 != null)
                return false;
        } else if (!team1.equals(other.team1))
            return false;
        if (team2 == null) {
            if (other.team2 != null)
                return false;
        } else if (!team2.equals(other.team2))
            return false;
        if (type == null) {
            if (other.type != null)
                return false;
        } else if (!type.equals(other.type))
            return false;
        if (umpire == null) {
            if (other.umpire != null)
                return false;
        } else if (!umpire.equals(other.umpire))
            return false;
        return true;
    }    
    @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 + "]";
    }            
}

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')
);

Like us on Facebook