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