0
votes

We have three tables TABLE_A, TABLE_B and TABLE_C. A&B have one-to-one mapping with a foreign key (both tables have same Primary ID). B & C have one to many relationship. I've defined the hibernate mapping as below.

<class name="com.test.ClassA" table="TABLE_A">
        <id name="aId" type="long">
            <column name="A_ID" />
            <generator class="assigned" />
        </id>
        <one-to-one name="classB" class="com.test.ClassB"   cascade="all" lazy="false"/>
    </class>
    <class name="com.test.classB" table="TABLE_B">
        <id name="aId" type="long">
            <column name="A_ID" />
            <generator class="assigned"/>
        </id>
        <one-to-one name="classA" class="com.test.ClassA" constrained="true"/>
        <set name="listOfC" table="TABLE_C" inverse="false"     lazy="false" fetch="select" cascade="all-delete-orphan">
            <key>
                <column name="A_ID" not-null="true"/>
            </key>
            <one-to-many class="com.test.ClassC"/>
        </set>
    </class>
    <class name="com.test.ClassC"   table="TABLE_C">
        <id name="id" type="long">
            <column name="ID" />
            <generator class="identity"/>
        </id>
        <many-to-one name="classB" class="com.test.ClassB"  fetch="select">
            <column name="A_ID"/>
        </many-to-one>
    </class>

When I try to insert/update ClassA, both B and C get saved. But I'm getting constraint violation exception when trying to delete A.

get & delete logic

public ClassA getClassA(final long aID)throws HibernateException, SQLException
{ 
    HibernateCallback callback = new HibernateCallback() 
    {
        public Object doInHibernate(Session session) throws HibernateException, SQLException 
        {
            Criteria hctr = session.createCriteria(ClassA.class);
            hctr.add(Restrictions.eq("A_ID", aID));
            return hctr.list();
        }
    };
    List list = (List)this.getHibernateTemplate().execute(callback);
    if(list==null || list.size()==0)
    {
        return null;
    }
    return (ClassA)list.get(0);
}

public void deleteClassA(long aId)throws HibernateException, SQLException { ClassA classA = getClassA(aId); if(classA!=null) { this.getHibernateTemplate().delete(classA); } }

update TABLE_C set A_ID=null where A_ID=?]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not delete collection: [com.test.ClassB.listOfC#77675] at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:659) at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:414) at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:416) at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:379) at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:887) at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:882) Caused by: com.ibm.db2.jcc.am.oo: Assignment of a NULL value to a NOT NULL column "TBSPACEID=3, TABLEID=480, COLNO=1" is not allowed.. SQLCODE=-407, SQLSTATE=23502, DRIVER=3.58.81

For some reason, Hibernate is trying to update TABLE_C entry with null value instead of deleting it. One thing I've observed is that, when the classA is loaded using the getClassA() funciton, "aId" value in ClassC is null. I've verified the table and the value does exist. No idea why it is null when reading from DB.

1

1 Answers

0
votes

To make cascade.delete working hibernate need to pass the entity to the delete operation not the id. Then in you case replace deleteClassA(long aId) by deleteClassA(A a) see this link Hibernate delete objects on cascade