13 - Collection Mapping in Hibernate: Page 4 of 4

13.3.5 Map Implementation

Map is a key value pair and hibernate does provide <map> tag to support java.util.Map. HashMap should be used as an implementation Folder.java

package com.tutorial.hibernate;

import java.util.HashMap;
import java.util.Map;

public class Folder {

      private int folderId;    
      private String folderName;    
      private Map<String,File> files = new HashMap<String,File>();

      public int getFolderId() {
        return folderId;
    }
    public void setFolderId(int folderId) {
        this.folderId = folderId;
    }
    public String getFolderName() {
        return folderName;
    }
    public void setFolderName(String folderName) {
        this.folderName = folderName;
    }
    public Map<String,File>getFiles() {
        return files;
    }
    public void setFiles(Map<String,File> files) {
        this.files = files;
    }
}

We need to use <map> tag and one extra column will be created in table to hold the keys of map

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
 "-//Hibernate/Hibernate Mapping DTD//EN"
 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
  <class name="com.tutorial.hibernate.Folder" table="Folder">
    <id name="folderId" type="int" column="folder_id">
       <generator class="native"/>
     </id>

     <property name="folderName" column="name" type="string"/>

     <map name="files" table="Files" >
         <key column="folderIdForeignKey"></key>
         <map-key  type="string" column="file_key" ></map-key>

        <composite-element class="com.tutorial.hibernate.File">
            <property name="name" type="string" column="file_name"/>
            <property name="size" type= "int" column="file_size"/>
            <property name="extension" type="string" column="file_ext"/>
         </composite-element>

     </map>

   </class>
</hibernate-mapping>

Create Tables 

CREATE TABLE 'folder' (
  'folder_id' int(11) NOT NULL AUTO_INCREMENT,
  'name' varchar(255) DEFAULT NULL,
  PRIMARY KEY ('folder_id')
);

CREATE TABLE 'files' (
  'folderIdForeignKey' int(11) NOT NULL,
  'file_name' varchar(255) DEFAULT NULL,
  'file_size' int(11) DEFAULT NULL,
  'file_ext' varchar(255) DEFAULT NULL,
  'file_key' varchar(255) NOT NULL,
  PRIMARY KEY ('folderIdForeignKey','file_key'),
  CONSTRAINT 'FK_n1d8h7ymasle0im3hk2dtxswt' FOREIGN KEY ('folderIdForeignKey') REFERENCES 'folder' ('folder_id')
)

Test Program

import com.tutorial.hibernate.File;
import com.tutorial.hibernate.Folder;

import java.util.HashMap;
import java.util.Map;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class Test {
  
     public static void main(String args[])
     {

        Configuration cfg = new Configuration().configure();        
        SessionFactory factory = cfg.buildSessionFactory();
        Session session=  factory.openSession();

        Transaction tx = session.beginTransaction();        
        Folder folder = new Folder();        
        folder.setFolderName("folder1");
  
        Map<String,File> files = new HashMap<String,File>();

        File f1= new File();
        f1.setExtension(".txt");
        f1.setName("sample");
        f1.setSize(102);

        File f2= new File();
        f2.setExtension(".xls");
        f2.setName("data");
        f2.setSize(1024);

        files.put("F1", f1);
        files.put("F2",f2);

        folder.setFiles(files); 

        session.save(folder);

        Query q = session.createQuery("from Folder");        
        Folder f =(Folder) q.uniqueResult();

        System.out.println(f.getFiles());
        tx.commit();
        session.close();
  
        factory.close();
    }
}

Run Test Program

 

13.3.6 SortedMap Implementation

In case we want to have the files map sorted , we can use SortedMap interface  hibernate does provide <map> tag to support java.util.Map. TreeMap should be used as an implementation.

In a <map> tag we can use sort attribute to

  • specify the Comparator class which will be used to sort the set when the files will be retrieved.
  • Instead of specifying comparator we can use “natural”  in which compareTo method will be used for sorting.

Folder.java

package com.tutorial.hibernate;

import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

public class Folder {

       private int folderId;    
       private String folderName;    
       private SortedMap<String,File> files = new TreeMap<String,File>();

       public int getFolderId() {
        return folderId;
       }
       public void setFolderId(intfolderId) {
         this.folderId = folderId;
       }
       public String getFolderName() {
         return folderName;
       }
       public void setFolderName(String folderName) {
         this.folderName = folderName;
       }
       public SortedMap<String,File>getFiles() {
         return files;
       }
       public void setFiles(SortedMap<String,File> files) {
        this.files = files;
      }
 }

Mapping file 

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
 "-//Hibernate/Hibernate Mapping DTD//EN"
 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   <class name="com.tutorial.hibernate.Folder" table="Folder">
      <id name="folderId" type="int" column="folder_id">
          <generator class="native"/>
      </id>

      <property name="folderName" column="name" type="string"/>

      <map name="files" table="Files" sort="com.tutorial.hibernate.ReverseFileComparator">
            <key column="folderIdForeignKey"></key>
            <map-key  type="string" column="file_key" ></map-key>

            composite-element class="com.tutorial.hibernate.File">
               <property name="name" type="string" column="file_name"/>
               <property name="size" type= "int" column="file_size"/>
               <property name="extension" type="string" column="file_ext"/>
            </composite-element>
      </map>
   </class>
</hibernate-mapping>

 

Comparator

package com.tutorial.hibernate;

import java.util.Comparator;

public class ReverseFileComparator implements Comparator<String>{

       @Override
       public int compare(String  s1, String s2) {
 
       return  s1.compareTo(s2) * -1;
    }
}

Test.java

import com.tutorial.hibernate.File;
import com.tutorial.hibernate.Folder;

import java.util.SortedMap;
import java.util.TreeMap;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class Test {

      public static void main(String args[])
      {

        Configuration cfg = new Configuration().configure();        
        SessionFactory factory = cfg.buildSessionFactory();
        Session session=  factory.openSession();

        Transaction tx = session.beginTransaction();        
        Folder folder = new Folder();        
        folder.setFolderName("folder1");

        SortedMap<String,File> files = new TreeMap<String,File>();

        File f1= newFile();
        f1.setExtension(".txt");
        f1.setName("sample");
        f1.setSize(102);

        File f2= newFile();
        f2.setExtension(".xls");
        f2.setName("data");
        f2.setSize(1024);

        files.put("F1", f1);
        files.put("F2",f2);

        folder.setFiles(files);
        session.save(folder);

        tx.commit();
        session.close();

        session=  factory.openSession();

        Query q = session.createQuery("from Folder");        
        Folder f =(Folder) q.uniqueResult();

        System.out.println(f.getFiles());        
        session.close();        
        factory.close();
    }
}

Run Test Program 

 

Changing sort to natural will display Files in sorted order of key

 

 

Like us on Facebook