Collection mapping table
HBM Element | Java Interface | Java Implementation |
<set> | Set | HashSet |
<set> with order | SortedSet | TreeSet |
<list> | List | ArrayList |
<bag>, <idbag> | Collection | ArrayList |
<map> | Map | HashMap |
<map> with order | SortedMap | TreeMap |
<array>, <primitive-array> | N/A | array |
Sample Tables
CREATE TABLE `core_sample_company` (
`companyId` decimal(18,0) NOT NULL,
`companyName` varchar(128) NOT NULL,
`description` varchar(1024) default NULL,
PRIMARY KEY (`companyId`)
);
CREATE TABLE `core_sample_role` (
`roleId` decimal(18,0) NOT NULL,
`roleName` varchar(128) NOT NULL,
`companyId` decimal(18,0) NOT NULL,
`description` varchar(1024) default NULL,
PRIMARY KEY (`roleId`)
);
CREATE TABLE `core_sample_user` (
`userId` decimal(18,0) NOT NULL,
`userName` varchar(128) NOT NULL,
`companyId` decimal(18,0) NOT NULL,
`defaultRoleId` decimal(18,0) default NULL,
`description` varchar(1024) default NULL,
PRIMARY KEY (`userId`)
);
CREATE TABLE `core_sample_user_role` (
`userId` decimal(18,0) NOT NULL,
`roleId` decimal(18,0) NOT NULL,
`pripority` int(11) NOT NULL,
PRIMARY KEY (`userId`,`roleId`)
);
HBM defintion
The definiton of <set>, <bag>, <list> is similar.
Defines a collection whose element type is simple data type.
<class name="SampleCompany" table="core_sample_company">
<bag name="roleNames" table="core_sample_role" lazy="false" >
<key column="companyId"/>
<element column="roleName" type="string"/>
</bag>
</class>
Query HQL: select c.id, c.name, r from SampleCompany c left join c.roleNames r
Defines a collection whose element type is another mapped java class
<class name="SampleCompany" table="core_sample_company">
<bag name="roles" cascade="none">
<key column="companyId"/>
<one-to-many class="SampleRole" not-found="ignore"/>
</bag>
</class>
Query HQL: select c.id, c.name, r.name from SampleCompany c left join c.role r
Pay attention that key column is a foreign column of SampleRole table.
Defines a list with list-index
<list> is not a popular element. It request a index column in table. The index column is the index of java List, it has to be a sequence starts from 0.
<class name="SampleUser" table="core_sample_user">
<list name="roles" table="core_sample_user_role" cascade="all" lazy="false" >
<key><column name="userId" sql-type="integer"/></key>
<index column="priority"></index>
<many-to-many class="SampleRole">
<column name="roleId"></column>
</many-to-many>
</list>
</class>
The benifit of <list> is it alwasy sorts list by index column. However, It is hard to resort the list. I tried remove a role from role list and add it to another poisition. When save the role list, an exception throwed:
java.sql.BatchUpdateException: Duplicate entry 'user001-role003 for key 1
This should be a hibernate bug.
Defines a bag with relationship table
<class name="SampleRole" table="core_sample_role">
<bag name="users" table="core_sample_user_role" cascade="none" lazy="false">
<key><column name="roleId" sql-type="integer"/></key>
<many-to-many class="SampleUser">
<column name="userId"></column>
</many-to-many>
</bag>
</class>
- Key column is foreign column from relationship table to current table(SampleRole>
- many-to-many sub column is foreign column from relationship table to target table (SampleUser)