Hibernate – SortedSet Mapping

SortedSet can be viewed in a group of elements and they do not have a duplicate element and ascending order is maintained in its elements. By using <set> elements we can use them and the entity should have a Sortedset of values. As an example, we can have a freelancer who works for multiple companies on a shift basis. Here also the one-to-many relationship is seen as a freelancer can belong to multiple (many) companies.

Example Project

Project Structure:

 

This is a maven project. Let us see pom.xml

pom.xml

XML




<project 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
                             https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>HibernateSortedSetMapping</groupId>
  <artifactId>HibernateSortedSetMapping</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <build>
    <sourceDirectory>src</sourceDirectory>
    <resources>
      <resource>
        <directory>src</directory>
        <excludes>
          <exclude>**/*.java</exclude>
        </excludes>
      </resource>
    </resources>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <release>9</release>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.4.15.Final</version>
        </dependency>
        <!-- As we are connecting with MySQL, this is needed -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>
    </dependencies>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
</project>


Let us start with POJO classes

Freelancer.java

Java




import java.util.SortedSet;
 
public class Freelancer {
    // data members
    private int freelancerId;
    private String freelancerName;
    private int freelancerAge;
    private int pricePerHour;
    // As one freelancer works for multiple companies, let
    // us have that as SortedSet here for companies
    private SortedSet companies;
 
    public int getFreelancerId() { return freelancerId; }
    public void setFreelancerId(int freelancerId)
    {
        this.freelancerId = freelancerId;
    }
    public String getFreelancerName()
    {
        return freelancerName;
    }
    public void setFreelancerName(String freelancerName)
    {
        this.freelancerName = freelancerName;
    }
    public int getFreelancerAge() { return freelancerAge; }
    public void setFreelancerAge(int freelancerAge)
    {
        this.freelancerAge = freelancerAge;
    }
    public int getPricePerHour() { return pricePerHour; }
    public void setPricePerHour(int pricePerHour)
    {
        this.pricePerHour = pricePerHour;
    }
    public SortedSet getCompanies() { return companies; }
    public void setCompanies(SortedSet companies)
    {
        this.companies = companies;
    }
    // no argument constructor
    public Freelancer() {}
    // argument constructor
    public Freelancer(String freelancerName,
                      int freelancerAge, int pricePerHour)
    {
        this.freelancerName = freelancerName;
        this.freelancerAge = freelancerAge;
        this.pricePerHour = pricePerHour;
    }
}


Company.java

Java




public class Company implements Comparable<Company> {
    private int companyId;
    private String companyName;
    public int getCompanyId() { return companyId; }
 
    public void setCompanyId(int companyId)
    {
        this.companyId = companyId;
    }
 
    public String getCompanyName() { return companyName; }
 
    public void setCompanyName(String companyName)
    {
        this.companyName = companyName;
    }
 
    public Company(String companyName)
    {
        this.companyName = companyName;
    }
 
    public Company() {}
 
    @Override
    // This method has to be implemented as we are following
    // SortedSet
    public int compareTo(Company company)
    {
        if (company == null) {
            return -1;
        }
        Comparable company1 = this.getCompanyName();
        Comparable company2 = company.getCompanyName();
        if (company1 == null) {
            return 1;
        }
        else if (company2 == null) {
            return -1;
        }
        else {
            return company1.compareTo(company2);
        }
    }
}


Let us see the configuration files

hibernate.cfg.xml

XML




<?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>
     
          <!--  As we are connecting mysql, those driver classes, database name,
              username and password are specified
              Please change the information as per your requirement -->
       
        <!-- This property creates table in MySQL automatically
             according to the specifications
             given in mapping resource file which in turn maps to the POJO class -->
        <property name="hbm2ddl.auto">update</property
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/w3wiki?serverTimezone=UTC</property>       
        <property name="connection.username">root</property>
        <property name="connection.password">admin</property>
         
          <!-- Helps to show the correct sql for each
             and every hibernate operation -->
        <property name="show_sql">true</property>
         
           <!--  We are going to connect language.hbm.xml and
               book.hbm.xml which has the table information
               about programmingLanguages and book which is present in mysql -->
         <mapping resource="freelancer.hbm.xml"/>
        <mapping resource="company.hbm.xml"/>
       
    </session-factory>
</hibernate-configuration>


freelancer.hbm.xml

XML




<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping SYSTEM
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
   
  <!-- In MySQL, 'freelancer' table is created if it is not there and it
       should have 4 attributes namely freelancerId, freelancerName,
       freelancerAge  and pricePerHour -->
 <class name="com.gfg.sortedsetmapping.pojo.Freelancer" table="freelancer">
  <id name="freelancerId" type="int" column="freelancerId">
    <generator class="native"></generator>
  </id>
  <property name="freelancerName" column="freelancerName" type="string"/>
  <property name="freelancerAge" column="freelancerAge" type="int"/>
  <property name="pricePerHour" column="pricePerHour" type="int"/>
   
       <!-- We are following SortedSet Pattern. Hence should provide 'set' and also 'sort' nature
          Here one to many relationship is followed and it denote a key column as well -->
  <set name="companies" cascade="all"  sort="natural">
       <key column="freelancerId"/>
       <one-to-many class="com.gfg.sortedsetmapping.pojo.Company"/>
  </set>
 </class>
   
</hibernate-mapping>


company.hbm.xml

XML




<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping SYSTEM
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  
    <!-- In MySQL, 'company' table is created if it is not there and it
         should have 2 attributes namely companyId and companyName -->
<hibernate-mapping>
   
  <class name="com.gfg.sortedsetmapping.pojo.Company" table="company">
    <id name="companyId" type="int" column="companyId">
    <generator class="native"></generator>
    </id>
    <property name="companyName" column="companyName" type="string"></property>
  </class>
   
</hibernate-mapping>


SortedSetMappingPatternOfStoringData.java

Java




import com.gfg.sortedsetmapping.pojo.Company;
import com.gfg.sortedsetmapping.pojo.Freelancer;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
 
public class SortedSetMappingPatternOfStoringData {
    private static SessionFactory factory;
 
    public static void main(String[] args)
    {
 
        try {
            factory = new Configuration()
                          .configure()
                          .buildSessionFactory();
        }
        catch (Throwable ex) {
            System.err.println(
                "Failed to create sessionFactory object."
                + ex);
            throw new ExceptionInInitializerError(ex);
        }
 
        // As one freelancer works for multiple companies,
        // via TreeSet we can represent that
        TreeSet companySet1 = new TreeSet();
        companySet1.add(new Company("Company A"));
        companySet1.add(new Company("Company B"));
 
        TreeSet companySet2 = new TreeSet();
        companySet2.add(new Company("Company A"));
        companySet2.add(new Company("Company C"));
        companySet2.add(new Company("Company E"));
 
        // Create the Freelancer object.
        Freelancer freelancer1
            = new Freelancer("Freelancer A", 20, 1000);
        freelancer1.setCompanies(
            companySet1); // Freelancer A associated to 2
        // companies
 
        Freelancer freelancer2
            = new Freelancer("Freelancer B", 20, 2000);
        freelancer2.setCompanies(
            companySet2); // Freelancer B associated to 2
        // companies
 
        SortedSetMappingPatternOfStoringData
            sortedMapMappingPatternOfStoringData
            = new SortedSetMappingPatternOfStoringData();
        // insert freelancer object.
        Integer freelancerId1
            = sortedMapMappingPatternOfStoringData
                  .addFreelancer(freelancer1);
 
        Integer freelancerId2
            = sortedMapMappingPatternOfStoringData
                  .addFreelancer(freelancer2);
 
        // show all Language and book details object.
        sortedMapMappingPatternOfStoringData
            .listFreelancerAndCompanyDetails();
    }
 
    public Integer addFreelancer(Freelancer freelancer)
    {
        Session session = factory.openSession();
        Transaction tx = null;
        Integer languageId = null;
        try {
            tx = session.beginTransaction();
            languageId = (Integer)session.save(freelancer);
            tx.commit();
        }
        catch (HibernateException e) {
            if (tx != null)
                tx.rollback();
            e.printStackTrace();
        }
        finally {
            session.close();
        }
        return languageId;
    }
 
    // Method to list all the freelancers and company detail
    public void listFreelancerAndCompanyDetails()
    {
        Session session = factory.openSession();
        Transaction tx = null;
 
        try {
            tx = session.beginTransaction();
            List<Freelancer> freelancers
                = session.createQuery("FROM Freelancer")
                      .list();
            for (Freelancer freelancer : freelancers) {
                System.out.println(
                    "Freelancer Name: "
                    + freelancer.getFreelancerName());
                System.out.println(
                    "Freelancer Age: "
                    + freelancer.getFreelancerAge());
                System.out.println(
                    "Price Per Hour: "
                    + freelancer.getPricePerHour());
                Set<Company> companies
                    = freelancer.getCompanies();
                for (Company company : companies) {
                    System.out.println(
                        "Company Name:"
                        + company.getCompanyName());
                }
            }
            tx.commit();
        }
        catch (HibernateException e) {
            if (tx != null)
                tx.rollback();
            e.printStackTrace();
        }
        finally {
            session.close();
        }
    }
}


On execution of the project.

Output:

 

Conclusion

The one-to-many relationship can be easily depicted via SortedSet and from the output, it is proved that no duplicate elements and ascending order is maintained in the output.