Hibernate Embeddable Composite Primary Key | @Embeddable, @EmbeddedId

Hibernate Embeddable Composite Primary Key

Creating table

Create EMPLOYEE Table, simply Copy and Paste the following SQL query in the query editor to get the table created.
CREATE TABLE "EMPLOYEE" 
   (
        "EMP_ID" NUMBER(10,0) NOT NULL ENABLE, 
 "EMP_NAME" VARCHAR2(255 CHAR), 
 "DEPARTMENT" VARCHAR2(255 CHAR), 
 PRIMARY KEY(EMP_ID,DEPARTMENT)
   );


  1. Create a simple Maven Project “HibernateTutorial” and create a package for our source files com.javainterviewpoint” under  src/main/java 
  2. Now add the following dependency in the POM.xml
     xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
       4.0.0
HibernateTutorial HibernateTutorial 0.0.1-SNAPSHOT 4.3.11.Final 11.2.0 org.hibernate hibernate-core ${hibernate.version} com.oracle ojdbc14 ${oracle.connector.version} src maven-compiler-plugin 3.3 1.7 1.7
  • Create the Java classes Employee.java, EmployeeId.java and CompositeKey_Embeddable_Example.java under  com.javainterviewpoint folder.
  • Place the hibernate.cfg.xml under thesrc/main/resources  directory
  • EmployeeId.java

    package com.javainterviewpoint;
    
    import java.io.Serializable;
    
    import javax.persistence.Column;
    import javax.persistence.Embeddable;
    
    @Embeddable
    public class EmployeeId implements Serializable
    {
        private static final long serialVersionUID = 1L;
        @Column(name = "EMP_ID")
        private int empId;
        @Column(name = "DEPARTMENT")
        private String department;
    
        public EmployeeId()
        {
            super();
        }
        public EmployeeId(int empId, String department)
        {
            super();
            this.empId = empId;
            this.department = department;
        }
    
        public int getEmpId()
        {
            return empId;
        }
        public void setEmpId(int empId)
        {
            this.empId = empId;
        }
        public String getDepartment()
        {
            return department;
        }
        public void setDepartment(String department)
        {
            this.department = department;
        }
        @Override
        public int hashCode()
        {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((department == null) ? 0 : department.hashCode());
            result = prime * result + empId;
            return result;
        }
        @Override
        public boolean equals(Object obj)
        {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            EmployeeId other = (EmployeeId) obj;
            if (department == null)
            {
                if (other.department != null)
                    return false;
            } else if (!department.equals(other.department))
                return false;
            if (empId != other.empId)
                return false;
            return true;
        }
    }
    In order to implement Composite Key in Hibernate, we need to override the equals() and hashCode() method and also implement the Serializable interface. Our EmployeeId class act as the ID class and we have marked it with @Embeddableannotation so that this class is eligible to be an embeddableclass.

    Employee.java

    package com.javainterviewpoint;
    
    import java.io.Serializable;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    @Entity
    public class Employee implements Serializable
    {
        private static final long serialVersionUID = 1L;
        @EmbeddedId
        EmployeeId id;
        @Column(name="EMP_NAME")
        private String empName;
        
        public Employee()
        {
            super();
        }
        public Employee(EmployeeId id, String empName)
        {
            super();
            this.id = id;
            this.empName = empName;
        }
        public EmployeeId getId()
        {
            return id;
        }
        public void setId(EmployeeId id)
        {
            this.id = id;
        }
        public String getEmpName()
        {
            return empName;
        }
        public void setEmpName(String empName)
        {
            this.empName = empName;
        }
    }
    Our primary key fields(empId and department) are defined in our embeddable class (EmployeeId). The Employee Entity class contains a single primary key field (EmployeeId) that is annotated with @EmbeddedId and contains an instance of that embeddable class.

    hibernate.cfg.xml

    Place the hibernate.cfg.xml file also under the src/main/resources folder
     xml version='1.0' encoding='utf-8'?>
    
    
    
    
     
    
     
      name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver
      name="hibernate.connection.username">root
      name="hibernate.connection.password">root
      name="hibernate.connection.url">jdbc:oracle:thin:@mydb:40051:dev
    
     
      name="connection.pool_size">1
    
     
      name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect
    
     
      name="show_sql">true
    
     
      name="hibernate.hbm2ddl.auto">update
    
     
      class="com.javainterviewpoint.Employee"/>
      class="com.javainterviewpoint.EmployeeId"/>
    
    • First and foremost property is for specifying the JDBC Driver class, in my case it OracleDriver
     name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver
    • Give the connection URL for connecting the database and provide username and password for connecting the above database
     name="hibernate.connection.url">jdbc:oracle:thin:@mydb:40051:dev
     name="hibernate.connection.username">root
     name="hibernate.connection.password">root
    • Specify the connection pool size, this property limits the number of connections in the Hibernate connection pool.
     name="connection.pool_size">1
    • Dialect Property makes the Hibernate generate the SQL for the corresponding database which is being used. In this example we are using Oracle database hence Oracle querywill be generated. If you are using MySQL database then you need to change the dialect accordingly.
     name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect
    • The show_sql property will print the executed sql in the console when set to true.
     name="show_sql">true
    • If the property “hibernate.hbm2ddl.auto” is set to “create”  This will drop and recreate the database schema on every execution. If it is set to “update” then the database schema will be updated every time rather than dropping and recreating.
     name="hibernate.hbm2ddl.auto">update
    • Under the Mapping resource tag, we need to specify all the mapping class for which we need the table to be created or updated.
     class="com.javainterviewpoint.Employee"/>
     class="com.javainterviewpoint.EmployeeId"/>

    CompositeKey_Embeddable_Example.java

    package com.javainterviewpoint;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.service.ServiceRegistry;
    
    public class CompositeKey_Embeddable_Example
    {
               public static void main(String args[])
            {
                //Reading the hibernate configuration file
                Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
                StandardServiceRegistryBuilder regBuilber = new StandardServiceRegistryBuilder();
                regBuilber.applySettings(configuration.getProperties());
                ServiceRegistry serviceRegistry = regBuilber.build();
                
                //Create SessionFacctory
                SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
                
                //Create Session from SessionFactory
                Session session = sessionFactory.openSession();
                
                //Begin the transaction
                session.beginTransaction();
                
                //Create a new Employee object
                Employee employee = new Employee();
                
                EmployeeId employeeId = new EmployeeId(1,"Blogging");
                employee.setEmpName("JavaInterviewPoint");
                employee.setId(employeeId);
                
                session.save(employee);
                            
                //Retrieve Employee Details
                Employee employee1 = (Employee) session.get(Employee.class, employeeId);
                System.out.println("*** Employee Details ***");
                System.out.println("Employee Id   : "+employee1.getId().getEmpId());
                System.out.println("Employee Name : "+employee1.getEmpName());
                System.out.println("Department    : "+employee1.getId().getDepartment());
                
                //Commit the changes
                session.getTransaction().commit();
                //Close the session
                session.close();
            }
    }
    • Create the Configuration object and read the configuration file using the configure() method.
    Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
    • Get the SessionFactory object through the buildSessionFactory() method of the configuration object.
    SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
    • openSession() method opens up the new session and begin a new transaction
    Session session = sessionFactory.openSession();
    session.beginTransaction();
    • Create Employee and EmployeeId object and set values to its properties
    //Create a new Employee object
    Employee employee = new Employee();
    //set value to its properties
    EmployeeId employeeId = new EmployeeId(1,"Blogging");
    employee.setEmpName("JavaInterviewPoint");
    employee.setId(employeeId);
    • save() method of the session object will persistthe Employee object
    session.save(employee);
    • We can retrieve the Employee details by just passing IDclass (EmployeeId)
    Employee employee1 = (Employee) session.get(Employee.class, employeeId);
    System.out.println("*** Employee Details ***");
    System.out.println("Employee Id   : "+employee1.getId().getEmpId());
    System.out.println("Employee Name : "+employee1.getEmpName());
    System.out.println("Department    : "+employee1.getId().getDepartment());
    • Finally get the transaction and commit the changes and close the session.
    session.getTransaction().commit();
    session.close();
    Console
    INFO: HHH000261: Table found: EMPLOYEE
    Mar 23, 2017 6:33:07 AM org.hibernate.tool.hbm2ddl.TableMetadata 
    INFO: HHH000037: Columns: [department, emp_name, emp_id]
    Mar 23, 2017 6:33:07 AM org.hibernate.tool.hbm2ddl.TableMetadata 
    INFO: HHH000108: Foreign keys: []
    Mar 23, 2017 6:33:07 AM org.hibernate.tool.hbm2ddl.TableMetadata 
    INFO: HHH000126: Indexes: [sys_c0015248]
    Mar 23, 2017 6:33:07 AM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
    INFO: HHH000232: Schema update complete
    *** Employee Details ***
    Employee Id   : 1
    Employee Name : JavaInterviewPoint
    Department    : Blogging
    Hibernate: insert into EMPLOYEE (EMP_NAME, EMP_ID, DEPARTMENT) values (?, ?, ?)
    Table

    Comments