Open In App

Hibernate – SortedMap Mapping

Last Updated : 16 Jun, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

SortedMap is a map that always maintains its corresponding entries in ascending key order. In Hibernate, using the <map> element and ‘sort’ as ‘natural’ we can maintain the SortedMap. Let us see that by using the one-to-many relationship concept. For example, for a programming language like Java, many books are written. If SortedMap is followed, the books are organized in alphabetical order. Let us see that via a sample project.

Example Project 

Project Structure:

Project Structure

 

Let us create MySQL tables.

-- Main table which has languagename like Java
CREATE TABLE `programmingLanguages` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `languageName` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
);
-- Child table that has book details related to a languageId and hence it is referred here
-- Via sortedmapping in hibernate, master detail relationship is getting set
CREATE TABLE `bookDetails` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `bookName` varchar(40) DEFAULT NULL,
  `authorName` varchar(30) DEFAULT NULL,
  `languageId` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ;

Maven-driven project. Let’s see the pom.xml file.

pom.xml

XML




         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>HibernateSortedMapMapping</groupId>
  <artifactId>HibernateSortedMapMapping</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’s start with POJO classes. As two tables are there, let’s have 2 POJO classes each for one table.

ProgrammingLanguages.java

Java




import java.util.SortedMap;
 
public class ProgrammingLanguages {
    // data members
    private int id;
    // As we are seeing SortedMap example, let us have the
    // books to be of java.util.SortedMap
    public SortedMap getBooks() { return books; }
    public void setBooks(SortedMap books)
    {
        this.books = books;
    }
    private String languageName;
    private SortedMap books;
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getLanguageName() { return languageName; }
    public void setLanguageName(String languageName)
    {
        this.languageName = languageName;
    }
    // no argument constructor
    public ProgrammingLanguages() {}
    // argument constructor
    public ProgrammingLanguages(String languageName)
    {
        this.languageName = languageName;
    }
}


Book.java

Java




public class Book implements Comparable<String> {
    private int id;
    private String bookName;
    public int getId() { return id; }
 
    public void setId(int id) { this.id = id; }
 
    public String getBookName() { return bookName; }
 
    public void setBookName(String bookName)
    {
        this.bookName = bookName;
    }
 
    public String getAuthorName() { return authorName; }
 
    public void setAuthorName(String authorName)
    {
        this.authorName = authorName;
    }
 
    private String authorName;
    // argument Constructor
    public Book(String bookName, String authorName)
    {
        this.bookName = bookName;
        this.authorName = authorName;
    }
    // No argument Constructor
    public Book() {}
    // This method has to be implemented as we are using
    // Comparable Sorting is getting followed for SortedMap
    @Override
    public int compareTo(String book)
    {
        if (this == null) {
            return 1;
        }
        else if (book == null) {
            return -1;
        }
        else {
            return this.compareTo(book);
        }
    }
}


Let us see the configuration files now

hibernate.cfg.xml

XML




<?xml version='1.0' encoding='UTF-8'?> 
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
<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 -->
        <property name="hbm2ddl.auto">update</property
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/geeksforgeeks?serverTimezone=UTC</property>       
        <property name="connection.username">root</property>
        <property name="connection.password">admin</property>
       
         <!-- This will be helpful to know how the
             data is getting queried in backend -->
         <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="language.hbm.xml"/>
        <mapping resource="book.hbm.xml"/>
       
    </session-factory>
</hibernate-configuration>


In the main configuration file, 2 mapping resources are added. Let us see them

language.hbm.xml

XML




<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping SYSTEM
  
<hibernate-mapping>
  
  <!-- Always keep the POJO class name and MySQL table name alike -->
 <class name="com.gfg.sortedmapmapping.pojo.ProgrammingLanguages" table="programminglanguages">
  <id name="id" type="int" column="id">
    <generator class="native"></generator>
  </id>
  
  <property name="languageName" column="languageName" type="string"/>
  
  <!-- For using SortedMap, we have to follow the below syntax
       key column is the connecting column between both the labels
       index column is required  for SortedMap and that is
       not required in the case of bag mapping
       Relationship followed here is one-to-many as one
       language can have multiple books -->
   <map name="books" cascade="all"  sort="natural" >
       <key column="languageId"/>
       <index column="Language_Class"  type="string"/>
       <one-to-many class="com.gfg.sortedmapmapping.pojo.Book"/>
  </map>
  
 </class>
  
</hibernate-mapping>


book.hbm.xml

XML




<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping SYSTEM
  
<hibernate-mapping>
  
  <class name="com.gfg.sortedmapmapping.pojo.Book" table="bookdetails">
    <id name="id" type="int" column="id">
    <generator class="native"></generator>
    </id>
  
    <property name="bookName" column="bookName" type="string"></property>
    <property name="authorName" column="authorName" type="string"></property>
  
  </class>
  
</hibernate-mapping>


Let us go for the main class which does the addition of programming language and books into the MySQL table and listing from there

SortedMapMappingPatternOfStoringData.java

Java




import com.gfg.sortedmapmapping.pojo.Book;
import com.gfg.sortedmapmapping.pojo.ProgrammingLanguages;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.security.auth.Subject;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
 
public class SortedMapMappingPatternOfStoringData {
    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);
        }
 
        // Let us add Java as programming language and for
        // that effectively 3 books (with author name)
        // details are added
        TreeMap map = new TreeMap();
        map.put("Java1", new Book("J2EE", "Dave Evans"));
        map.put("Java2", new Book("Core Java Volume I",
                                  "Cay S. Horstmann"));
        map.put("Java3",
                new Book("Effective Java", "Joshua Bloch"));
 
        // Create the Language object.
        ProgrammingLanguages language
            = new ProgrammingLanguages("Java");
        language.setBooks(map);
 
        SortedMapMappingPatternOfStoringData
            sortedMapMappingPatternOfStoringData
            = new SortedMapMappingPatternOfStoringData();
        // insert language object.
        Integer languageId
            = sortedMapMappingPatternOfStoringData
                  .addLanguage(language);
 
        // show all Language and book details object.
        sortedMapMappingPatternOfStoringData
            .listLanguageAndBookDetails();
    }
 
    /* Method to add programming languages in the database
     */
    public Integer
    addLanguage(ProgrammingLanguages language)
    {
        Session session = factory.openSession();
        Transaction tx = null;
        Integer languageId = null;
        try {
            tx = session.beginTransaction();
            languageId = (Integer)session.save(language);
            tx.commit();
        }
        catch (HibernateException e) {
            if (tx != null)
                tx.rollback();
            e.printStackTrace();
        }
        finally {
            session.close();
        }
        return languageId;
    }
 
    /* Method to list all the language and book detail */
    public void listLanguageAndBookDetails()
    {
        Session session = factory.openSession();
        Transaction tx = null;
 
        try {
            tx = session.beginTransaction();
            List programmingLanguages
                = session
                      .createQuery(
                          "FROM ProgrammingLanguages")
                      .list();
            for (Iterator iterator
                 = programmingLanguages.iterator();
                 iterator.hasNext();) {
                ProgrammingLanguages language
                    = (ProgrammingLanguages)iterator.next();
                System.out.print(
                    "Language Name: "
                    + language.getLanguageName());
 
                Map books = language.getBooks();
                System.out.println(
                    "Book Name:"
                    + ((Book)books.get("Java1"))
                          .getBookName());
                System.out.println(
                    "Author Name:"
                    + ((Book)books.get("Java1"))
                          .getAuthorName());
 
                System.out.println(
                    "Book Name:"
                    + ((Book)books.get("Java2"))
                          .getBookName());
                System.out.println(
                    "Author Name:"
                    + ((Book)books.get("Java2"))
                          .getAuthorName());
 
                System.out.println(
                    "Book Name:"
                    + ((Book)books.get("Java3"))
                          .getBookName());
                System.out.println(
                    "Author Name:"
                    + ((Book)books.get("Java3"))
                          .getAuthorName());
            }
            tx.commit();
        }
        catch (HibernateException e) {
            if (tx != null)
                tx.rollback();
            e.printStackTrace();
        }
        finally {
            session.close();
        }
    }
}


On running the project, we can see the below output in the console.

Output:

Output

 

Let us see the output explanation in detail

Output

 

Output

 

MySQL table output:

MySQL table output

 

Conclusion

In sorted mapping, the index column is a must and it is represented in the MySql output as well. While storing as well, according to the alphabetical order of book name, they are stored in MySQL



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads