HibernateException: null index column for collection

1. Symtom
When access one-to-many relation with collection mapping by list. You may be get this error

Caused by: org.hibernate.HibernateException: null index column for collection: org.ow2.bonita.runtime.model.Execution.executions

at org.hibernate.persister.collection.AbstractCollectionPersister.readIndex(AbstractCollectionPersister.java:710)

at org.hibernate.collection.PersistentList.readFrom(PersistentList.java:379)

at org.hibernate.loader.Loader.readCollectionElement(Loader.java:1008)

at org.hibernate.loader.Loader.readCollectionElements(Loader.java:646)

at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:591)

at org.hibernate.loader.Loader.doQuery(Loader.java:701)

at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)

at org.hibernate.loader.Loader.loadCollection(Loader.java:1994)

at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)

Follow is mapping xml
Employee.hbm.xml

<hibernate-mapping package="com.devjav">

  <class name="Employee" table="EMPLOYEE">

    <id name="employeeId" column="EMPLOYEE_ID">
      <generator class="native" />
    </id>

    <property name="firstname" />
    <property name="lastname" column="lastname" />
    <property name="birthDate" type="date" column="birth_date" />
    <property name="cellphone" column="cell_phone" />

  		<many-to-one name="department" class="com.devjav.Department" 
          not-null="true">
            <column name="department_id" />
        </many-to-one>

  </class>
</hibernate-mapping>

Department.hbm.xml

<hibernate-mapping package="com.devjav">

    <class name="Department" table="DEPARTMENT">

 		<id name="departmentId" type="java.lang.Long" column="DEPARTMENT_ID">
 			<generator class="native" />
 		</id>

        <property name="departmentName" column="DEPT_NAME"/>

    <list name="employees" table="employee" 
        inverse="false" cascade="all">
            <key column="department_id"  />
        <list-index column="idx" />
            <one-to-many class="com.devjav.Employee" />
        </list>
  </class>
</hibernate-mapping>

2. Problem

This issue happen when you retrieve collection and root cause when you persistence parent and child table wrong order.

So the index column cannot maintain by hibernate so that it always null. Following code will make null on index column

SessionFactory sf = HibernateUtil.getSessionFactory();
    Session session = sf.openSession();
    session.beginTransaction();

    Department department = new Department();
    department.setDepartmentName("R&D");
    session.save(department);

    Employee emp1 = new Employee("Nina", "Helen", "543543");
    Employee emp2 = new Employee("Tony", "Stack", "435454");
    emp1.setDepartment(department);
    emp2.setDepartment(department);
    session.save(emp1);
    session.save(emp2);

    session.getTransaction().commit();
    session.close();

The result of above code

mysql> select * from employee;
+-------------+-----------+----------+------------+------------+---------------+------+
| EMPLOYEE_ID | firstname | lastname | birth_date | cell_phone | department_id | idx  |
+-------------+-----------+----------+------------+------------+---------------+------+
|           1 | Nina      | Helen    | NULL       | 543543     |             1 | NULL |
|           2 | Tony      | Stack    | NULL       | 435454     |             1 | NULL |
+-------------+-----------+----------+------------+------------+---------------+------+

3. Solution
Using below code to make pesistence work with index column

SessionFactory sf = HibernateUtil.getSessionFactory();
    Session session = sf.openSession();
    session.beginTransaction();

    Department department = new Department();
    department.setDepartmentName("R&D");
    Employee emp1 = new Employee("Nina", "Helen", "543543");
    Employee emp2 = new Employee("Tony", "Stack", "435454");

    department.setEmployees(new ArrayList());
    department.getEmployees().add(emp1);
    department.getEmployees().add(emp2);

    session.save(department);

    session.getTransaction().commit();
    session.close();

And the result is perfect :)

mysql> select * from employee;
+-------------+-----------+----------+------------+------------+---------------+-----+
| EMPLOYEE_ID | firstname | lastname | birth_date | cell_phone | department_id | idx |
+-------------+-----------+----------+------------+------------+---------------+-----+
|           1 | Nina      | Helen    | NULL       | 543543     |             1 |   0 |
|           2 | Tony      | Stack    | NULL       | 435454     |             1 |   1 |
+-------------+-----------+----------+------------+------------+---------------+-----+
2 rows in set

Leave a Reply