In bidirectional association, we will have navigations in both direction, i.e, both side of the association will have the reference to the other side. The both side of the association will implement one of the collection interfaces, if it has the reference to the other entity.

In many-to-one/one-to-many relationship, multiple source objects can have relationship with same target object or same target object will have multiple source objects and from both direction the navigation is possible. Let’s consider CD and Artist. So multiple CDs can be written by same Artist or same Artist can have multiple CDs. So we will create two tables CD and Artist in the database and we will see how many-to-one/one-to-many relationship work step by step.

Now we will apply many-to-one/one-to-many relationship. So multiple CDs can be written by same Artist or the same Artist can have multiple CDs.

Step 1. Create tables

Create table – cd

CREATE TABLE `cd` (
  `cdId` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `cdTitle` varchar(50) NOT NULL,
  `artistId` bigint(20) unsigned NOT NULL,
  PRIMARY KEY (`cdId`),
  KEY `fk_artist` (`artistId`),
  CONSTRAINT `fk_artist` FOREIGN KEY (`artistId`) REFERENCES `artist` (`artistId`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;

 

Create table – artist

CREATE TABLE `artist` (
  `artistId` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `artistName` varchar(50) NOT NULL,
  PRIMARY KEY (`artistId`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;

 

Step 2. Create a java project in any Java based IDE and configure for hibernate jars.

Step 3. Create hibernate reverse engineering and configuration file.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-reverse-engineering PUBLIC "-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd">
<hibernate-reverse-engineering>
  <schema-selection match-catalog="hibernate_assoc"/>
  <table-filter match-name="cd"/>
  <table-filter match-name="artist"/>
</hibernate-reverse-engineering>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <!-- hibernate database specific dialect -->
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <!-- hibernate database specific driver -->
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <!-- hibernate database connection URL -->
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_assoc?zeroDateTimeBehavior=convertToNull</property>
    <!-- hibernate database username -->
    <property name="hibernate.connection.username">root</property>
    <!-- show sql in console -->
    <property name="hibernate.show_sql">true</property>
    <!-- format sql in cosole for better readability -->
    <property name="hibernate.format_sql">true</property>
    <!-- which context to use for sql processing -->
    <property name="hibernate.current_session_context_class">thread</property>
    <!-- translator for HSQL -->
    <property name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property>
    <!-- hibernate mapping resources or files -->
    <mapping resource="in/webtuts/hibernate/domain/Artist.hbm.xml"/>
    <mapping resource="in/webtuts/hibernate/domain/Cd.hbm.xml"/>
  </session-factory>
</hibernate-configuration>

 

Step 4. Create hibernate utility class which creates singleton SessionFactory from which Session object will be created.

package in.webtuts.hibernate.utils;

import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;

/**
 * Hibernate Utility class with a convenient method to get Session Factory
 * object.
 *
 * @author admin
 */
public class HibernateUtil {

    private static final SessionFactory sessionFactory;

    static {
        try {
            // Create the SessionFactory from standard (hibernate.cfg.xml)
            // config file.
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            // Log the exception.
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

 

Step 5. Create mapping xml file and POJO for artist table

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="in.webtuts.hibernate.domain.Artist" table="artist" catalog="hibernate_assoc">
        <id name="artistId" type="java.lang.Long">
            <column name="artistId" />
            <generator class="identity" />
        </id>
        <property name="artistName" type="string">
            <column name="artistName" length="50" not-null="true" />
        </property>
        <!-- one-to-many relationship -->
        <set name="cds" table="cd" inverse="true" lazy="true" fetch="select" cascade="all">
            <key>
                <column name="artistId" not-null="true" />
            </key>
            <one-to-many class="in.webtuts.hibernate.domain.Cd" />
        </set>
    </class>
</hibernate-mapping>
package in.webtuts.hibernate.domain;

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

/**
 * Artist generated by hbm2java
 */
public class Artist implements java.io.Serializable {

    private Long artistId;
    private String artistName;
    private Set cds = new HashSet(0);

    public Artist() {
    }

    public Artist(String artistName) {
        this.artistName = artistName;
    }

    public Artist(String artistName, Set cds) {
        this.artistName = artistName;
        this.cds = cds;
    }

    public Long getArtistId() {
        return this.artistId;
    }

    public void setArtistId(Long artistId) {
        this.artistId = artistId;
    }

    public String getArtistName() {
        return this.artistName;
    }

    public void setArtistName(String artistName) {
        this.artistName = artistName;
    }

    public Set getCds() {
        return this.cds;
    }

    public void setCds(Set cds) {
        this.cds = cds;
    }

}

 

Step 6. Create mapping xml file and POJO for cd table. Look at the xml file, we have <many-to-one /> which makes sure that multiple CDs can be written by same Artist.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="in.webtuts.hibernate.domain.Cd" table="cd" catalog="hibernate_assoc">
        <id name="cdId" type="java.lang.Long">
            <column name="cdId" />
            <generator class="identity" />
        </id>
        <!-- many-to-one relationship -->
        <many-to-one name="artist" class="in.webtuts.hibernate.domain.Artist" fetch="select" cascade="all">
            <column name="artistId" not-null="true" />
        </many-to-one>
        <property name="cdTitle" type="string">
            <column name="cdTitle" length="50" not-null="true" />
        </property>
    </class>
</hibernate-mapping>
package in.webtuts.hibernate.domain;

/**
 * Cd generated by hbm2java
 */
public class Cd implements java.io.Serializable {

    private Long cdId;
    private Artist artist;
    private String cdTitle;

    public Cd() {
    }

    public Cd(Artist artist, String cdTitle) {
        this.artist = artist;
        this.cdTitle = cdTitle;
    }

    public Long getCdId() {
        return this.cdId;
    }

    public void setCdId(Long cdId) {
        this.cdId = cdId;
    }

    public Artist getArtist() {
        return this.artist;
    }

    public void setArtist(Artist artist) {
        this.artist = artist;
    }

    public String getCdTitle() {
        return this.cdTitle;
    }

    public void setCdTitle(String cdTitle) {
        this.cdTitle = cdTitle;
    }

}

 

Step 7. Now we will create a main class for testing many-to-one/one-to-many.

many-to-one testing

package in.webtuts.hibernate.test;

import in.webtuts.hibernate.domain.Artist;
import in.webtuts.hibernate.domain.Cd;
import in.webtuts.hibernate.utils.HibernateUtil;
import java.io.Serializable;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 *
 * @author admin
 */
public class ManyToOneOneToManyTest {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Session session = null;
        Transaction transaction = null;
        try {
            //create Artist object
            Artist artist = new Artist();
            artist.setArtistName("Soumitra");

            //create CD
            Cd cd1 = new Cd();
            cd1.setCdTitle("Java");
            cd1.setArtist(artist);

            //create another CD
            Cd cd2 = new Cd();
            cd2.setCdTitle("PHP");
            cd2.setArtist(artist);

            //get current session from sessionfactory
            session = HibernateUtil.getSessionFactory().getCurrentSession();
            //begin transaction
            transaction = session.beginTransaction();
            //save artist - below save statement is required if you do not use property 'cascade' in many-to-one relationship
            //session.save(artist);
            //save CD and get the id for this CD
            Serializable cdId = session.save(cd1);
            //save another CD
            session.save(cd2);

            //load CD from the session
            Cd cd = (Cd) session.load(Cd.class, cdId);

            //display CD and Artist info
            System.out.println("Cd ID: " + cd.getCdId());
            System.out.println("Cd Title: " + cd.getCdTitle());
            System.out.println("Cd Artist ID: " + cd.getArtist().getArtistId());
            System.out.println("Cd Artist Name: " + cd.getArtist().getArtistName());
            //commit transaction, not required if autocommit is true
            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
            //rollback transaction on exception
            transaction.rollback();
        }
    }

}

 

one-to-many testing

package in.webtuts.hibernate.test;

import in.webtuts.hibernate.domain.Artist;
import in.webtuts.hibernate.domain.Cd;
import in.webtuts.hibernate.utils.HibernateUtil;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 *
 * @author admin
 */
public class ManyToOneOneToManyTest {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Session session = null;
        Transaction transaction = null;
        try {
            Artist artist = new Artist();
            artist.setArtistName("Soumitra");
            Set<Cd> cds = new HashSet<Cd>();

            Cd cd1 = new Cd();
            cd1.setCdTitle("Java");
            cd1.setArtist(artist);

            Cd cd2 = new Cd();
            cd2.setCdTitle("PHP");
            cd2.setArtist(artist);

            cds.add(cd1);
            cds.add(cd2);

            artist.setCds(cds);

            session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            Serializable artistId = session.save(artist);
            
            Artist a = (Artist) session.load(Artist.class, artistId);

            System.out.println("Artist ID: " + a.getArtistId());
            System.out.println("Artist Name: " + a.getArtistName());
            List<Cd> cdList = new ArrayList<Cd>(a.getCds());
            for (Cd cd : cdList) {
                System.out.println("CD ID: " + cd.getCdId());
                System.out.println("CD Title: " + cd.getCdTitle());
            }
            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        }
    }

}

 

Step 8. Run the main class and see the output as shown below. While we save values for artist and cd, the below values are stored into the database tables.

many-to-one

inserted data into artist table

 insert  into `artist`(`artistId`,`artistName`) values (1,'Soumitra')

 

inserted data into cd table

insert  into `cd`(`cdId`,`cdTitle`,`artistId`) values (1,'Java',1),(2,'PHP',1)

 

Console output

Hibernate:
    insert
    into
        hibernate_assoc.artist
        (artistName)
    values
        (?)
Hibernate:
    insert
    into
        hibernate_assoc.cd
        (artistId, cdTitle)
    values
        (?, ?)
Hibernate:
    insert
    into
        hibernate_assoc.cd
        (artistId, cdTitle)
    values
        (?, ?)
Cd ID: 1
Cd Title: Java
Cd Artist ID: 1
Cd Artist Name: Soumitra

 

one-to-many

inserted data into artist table

insert  into `artist`(`artistId`,`artistName`) values (10,'Soumitra')

 

inserted data into cd table

insert  into `cd`(`cdId`,`cdTitle`,`artistId`) values (17,'Java',10),(18,'PHP',10)

 

Console output

Hibernate:
    insert
    into
        hibernate_assoc.artist
        (artistName)
    values
        (?)
Hibernate:
    insert
    into
        hibernate_assoc.cd
        (artistId, cdTitle)
    values
        (?, ?)
Hibernate:
    insert
    into
        hibernate_assoc.cd
        (artistId, cdTitle)
    values
        (?, ?)
Artist ID: 10
Artist Name: Soumitra
CD ID: 17
CD Title: Java
CD ID: 18
CD Title: PHP

 

Thanks for your reading.

Tags:

I am a professional Web developer, Enterprise Application developer, Software Engineer and Blogger. Connect me on Roy Tutorials | TwitterFacebook Google PlusLinkedin | Reddit

Leave a Reply

Your email address will not be published. Required fields are marked *