One to Many Mapping


Requirements

  • Jdk 1.7
  • IDE (I am using Eclipse Kepler IDE)
  • Database (I am using mysql)

Download JPA One to Many Demo with jars
Download JPA One to Many Demo without jars

In one to many mapping, one row in a table mapped with one row or more than one row in another table.
One country can have multiple states. So one row of country table mapped with multiple row of state table. id (column) of country (table) is a primary key (pk) is mapped with c_id (column) of state (table). id (column) of state (table) is a primary key (pk).
The below image is the example of one to many mapping...

one-to-many-jpa-hibernate-table


Step-1:- Country.java

Country is an entity class, which have three properties id and name states, id is treated as primary key, name contains name of country and states is type of list, list contains State objects.
@Entity: This class is treated as entity class. If it is not declared then throws java.lang.IllegalArgumentException: Unknown entity. It contains one parameter Ex: @Entity(name="test"), if @Table is not defined, then it creates a table with name in @Entity(name="emp1") otherwise creates a table name of class as emp. The name of entity is by default class name. This name can be use in HQL queries like table name in normal SQL queries.
@Table is used to create table with given name.
@Id This property is treated as primary key.
@SequenceGenerator is used to create sequence in database.
@GeneratedValue is used hold the reference of sequence. Ex:- @SequenceGenerator(name = "c_gen", ...) --> @GeneratedValue(generator = "c_gen")
@Column(name="something") This annotation used on property level. If we don't declare column annotation, then JPA is treated by default column name as property name.

@OneToMany is used on list or set properties.
package com.groupofknowledge;

import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;

@Entity
public class Country {
    @Id
    @SequenceGenerator(name = "c_gen", sequenceName = "c_seq",
        allocationSize = 1, initialValue = 1, schema = "gok")
    @GeneratedValue(generator = "c_gen")
    private Integer id;
    private String name;

    @OneToMany(mappedBy = "country1") // 101; 'country1' value must match with property in State class
    private List<State> states;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<State> getStates() {
        return states;
    }
    public void setStates(List<State> states) {
        this.states = states;
    }
}

Step-2:- State.java

State is an entity class, which have three properties id and name country1, id is treated as primary key, name contains name of state and country1 is type of Country type instance.
@Entity: This class is treated as entity class. If it is not declared then throws java.lang.IllegalArgumentException: Unknown entity. It contains one parameter Ex: @Entity(name="test"), if @Table is not defined, then it creates a table with name in @Entity(name="emp1") otherwise creates a table name of class as emp. The name of entity is by default class name. This name can be use in HQL queries like table name in normal SQL queries.
@Table is used to create table with given name.
@Id This property is treated as primary key.
@SequenceGenerator is used to create sequence in database.
@GeneratedValue is used hold the reference of sequence. Ex:- @SequenceGenerator(name = "emp_gen", ...) --> @GeneratedValue(generator = "emp_gen")
@Column(name="something") This annotation used on property level. If we don't declare column annotation, then JPA is treated by default column name as property name.

@OneToMany is used on list or set properties. @JoinColumn is used make relation between country and state class. Passed value c_id is the name of column in state table.
package com.groupofknowledge;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;

@Entity
public class State {
    @Id
    @SequenceGenerator(name = "s_gen", sequenceName = "s_seq",
        allocationSize = 1, initialValue = 1, schema = "gok")
    @GeneratedValue(generator = "s_gen")
    private Integer id;
    private String name;

    @ManyToOne // This indicates the relation as many to one. It means many states mapped with one country
    @JoinColumn(name = "c_id") // This (c_id) is the column in state table
    private Country country1;
        // 101; 'country1' property must match with @OneToMany(mappedBy = "country1") in Country class

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;     }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Country getCountry1() {
        return country1;
    }
    public void setCountry1(Country country1) {
        this.country1 = country1;
    }
}

Step-3:- persistence.xml


Description:- persistence.xml file contains information of database. The specification of each tag is explained below...
<persistence-unit name="demo"></persistence-unit> tag has name="demo", which should match with javax.persistence.Persistence.createEntityManagerFactory("demo") in Main.java file.
<class>com.groupofknowledge.Emp</class> tag represents entity class.
In <property name="hibernate.show_sql" value="true"/> tag has a hibernate.show_sql property key, which contains boolean value. If value="true", it means query will be visible in console otherwise it will not be visible in console.
In <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> tag has a javax.persistence.jdbc.driver property key which indicates database driver details.
Example: The drivers are given as below for different database.
  • com.mysql.jdbc.Driver (MySql)
  • org.postgresql.Driver (PostgreSql)
  • oracle.jdbc.driver.OracleDriver (Oracle)
  • com.microsoft.sqlserver.jdbc.SQLServerDriver (SQL Server)
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test"/> has a javax.persistence.jdbc.url property key which indicates information of database connection.
The description of jdbc:mysql://localhost:3306/test is given as below...
  • localhost for local database, give IP address for remote database
  • 3306 database port
  • test database schema
Example: The different connection url's are given as below for different database.
  • jdbc:mysql://localhost:3306/test (MySql)
  • jdbc:postgresql://localhost:5432/test (PostgreSql)
  • jdbc:oracle:thin:@localhost:1521:xe (Oracle)
  • jdbc:sqlserver://MYPC\\SQLEXPRESS;databaseName=test (SQL Server)
In <property name="javax.persistence.jdbc.user" value="root"/> tag indicates the database user name.
In <property name="javax.persistence.jdbc.password" value="root" /> tag indicates the database password.
In <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> tag has a hibernate.dialect property used to generate query according to database
Example: The different dialect are given as below for different database.
  • org.hibernate.dialect.MySQLDialec (MySql)
  • org.hibernate.dialect.PostgreSQLDialect (PostgreSql)
  • org.hibernate.dialect.Oracle10gDialect (Oracle)
  • org.hibernate.dialect.SQLServerDialect (SQL Server)
In <property name="hibernate.hbm2ddl.auto" value="update"/> tag has a hibernate.hbm2ddl.auto property can contains any one value among create/update/validate/create-drop.
  • create It drops all tables and create new tables when EntityManagerFactory is initialized.
  • update It does not drop any table, it only updates the table schema.
  • validate It validates that the schema matches, make no changes to the schema of the database.
  • create-drop It drops all tables and create new tables when EntityManagerFactory is initialized. As well as it drops all tables when EntityManagerFactory is closed.
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="demo">
        <class>com.groupofknowledge.Emp</class>
        <class>com.groupofknowledge.EmpDetails</class>
        <class>com.groupofknowledge.Country</class>
        <class>com.groupofknowledge.State</class>
        <class>com.groupofknowledge.Teacher</class>
        <class>com.groupofknowledge.Student</class>
        <properties>
            <property name="hibernate.show_sql" value="true"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="root" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>
</persistence>

Step-5:- Main.java

After running this class, it will create two tables country and state.
package com.groupofknowledge;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Main {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("demo");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        Country c = new Country();
        c.setName("India");
        State s = new State();
        s.setName("Delhi");
        s.setCountry1(c);
        em.persist(c);
        em.persist(s);
        /*Country c = em.find(Country.class, 1);
        State s=new State();
        s.setName("Haryana");
        s.setCountry1(c);
        em.persist(s);*/

        em.getTransaction().commit();
    }
}
The relation of country and state is given as below...
country table have id 1 and name India, India have two states UP and Delhi, which have c_id (this is the reference of India) as a foreign key.

Result...


country (Table)

id(pk) name
1 India

state (Table)

id(pk) name c_id(fk)
1 UP 1
2 Delhi 1
Download JPA One to Many Demo with jars
Download JPA One to Many Demo without jars