Monday, July 28, 2014

Hibernate: Many to Many mapping Error

This is my 3rd month using Hibernate and still I have trouble understanding how it works completely. I'm currently building an information system for my campus, and I use Struts+Hibernate to get it organised.

My recent problem is related to the many-to-many relation between two table. Hibernate allows you to simplify Many-to-Many calls by using a collection object on the class. I have no problem when viewing the list but adding it seems to be more complex.



Here is the many-to-many mapping on my hibernate xml mapping file:

<!-- Mapping table: krs (KRS) -->
<class name="sisne.pojo.KRS" table="krs">
   <id name="krsId" type="integer" column="krs_id" />

   <!-- Many to One from krs to student: many krs exist for a student -->
   <many-to-one name="mahasiswa" class="sisne.pojo.Mahasiswa">
      <column name="mhs_username" not-null="true"/>
   </many-to-one>
        
   <property name="keterangan" type="string" column="keterangan" />
   <property name="diterima" type="character" column="diterima"/>
        
   <property name="semester" type="integer" column="semester" />
   <property name="tahunAjaran" type="integer" column="tahun_ajaran"/>
    
   <set name="daftarKelas" table="krs_kls"
      inverse="false" lazy="true" fetch="select" cascade="all">
      <key column="krs_id" />
      <many-to-many column="kls_id" class="sisne.pojo.Kelas" />
   </set>
</class>

It's a mapping for student enrollment, but it's in Indonesian. And I simply added new krs by executing this lines:

session.beginTransaction();
session.save(krs);
session.getTransaction().commit();

Now the problem is although I successfully added the krs, the krs_kls is not added properly: the krs_id value in table krs_kls does not follow the krs_id on table krs. All new items in krs_kls have krs_id = 0. There was no error whatsoever on the log, so it took me a while to solve this.

Apparently, I forgot that krs_id in table krs has auto_increment property. I did not declare it in the mapping, and hibernate ignore the id that is generated during the insert. Since it did not grab the id, it assume the id is 0. This problem is solved simply by adding a generator property on the mapping.

<class name="sisne.pojo.KRS" table="krs">
   <id name="krsId" type="integer" column="krs_id" >
   <generator class="native"/>
</id>
 
Hope it helps.

No comments: