13.3.3 List Implementation
Folder class will have a list of files so we need to design the Folder class as below. Since list is ordered collection , we need to specify a column name in <list-index> attribute to store the index of the list elements.
Folder.java
package com.tutorial.hibernate; import java.util.ArrayList; import java.util.List; public class Folder { private int folderId; private String folderName; private List<File> files = new ArrayList<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 List<File> getFiles() { return files; } public void setFiles(List<File> files) { this.files = files; } }
We will use <list> tag to define the Folder and File classes in component-mapping.hbm.xml .
- <key column> tag will create a column with the given name in the table configured in <set> and it will be a foreign key column for the primary key of Folder table. No need to create property in Object corresponding to this column as Hibernate does manages it internally.
- <list-index > is used to specify the column which will store the index to maintain the order. No need to create a property in Object corresponding to this column as Hibernate does manages it internally.
- <composite-element> tag defines the class name and its properties.
<?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"/> <list name="files" table="Files" > <key column="folderIdForeignKey"></key> <list-index column="position"></list-index> <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> </list> </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, 'position' int(11) NOT NULL, PRIMARY KEY ('folderIdForeignKey','position'), CONSTRAINT 'FK_n1d8h7ymasle0im3hk2dtxswt' FOREIGN KEY ('folderIdForeignKey') REFERENCES 'folder' ('folder_id') )
Test Program
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.SortedSet; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.tutorial.hibernate.File; import com.tutorial.hibernate.Folder; 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"); List<File> files = new ArrayList<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.add(f1); files.add(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. Database state will be as below
13.3.4 Collection Implementation
To support unordered and duplicated values , we can use Collection interface and ArrayList as an implementation . Hibernate does provide <bag> and <idbag> tags to map the Collections.
Folder class will have a collections of files (with arraylist as implementation ) so we need to design the Folder class as below.
Folder.java
package com.tutorial.hibernate; import java.util.ArrayList; import java.util.Collection; import java.util.List; public class Folder { private int folderId; private String folderName; private Collection<File> files = new ArrayList<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 Collection<File> getFiles() { return files; } public void setFiles(Collection<File> files) { this.files = files; } }
We will use <bag> tag to define the Folder and File classes in component-mapping.hbm.xml .
- <key column> tag will create a column with given name in the table configured in <bag> and it will be a foreign key column for the primary key of Folder table. No need to create property in Object corresponding to this column as Hibernate does manages it internally.
- <composite-element> tag defines the class name and its properties.
<?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"/> <bag name="files" table="Files" > <key column="folderIdForeignKey"></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> </bag> </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, KEY 'FK_n1d8h7ymasle0im3hk2dtxswt' ('folderIdForeignKey'), CONSTRAINT 'FK_n1d8h7ymasle0im3hk2dtxswt' FOREIGN KEY ('folderIdForeignKey') REFERENCES 'folder' ('folder_id') );
Test Program
import java.util.ArrayList; import java.util.Collection; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.tutorial.hibernate.File; import com.tutorial.hibernate.Folder; 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"); Collection<File> files = new ArrayList<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.add(f1); files.add(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(); } }