views:

37

answers:

1

I'm wondering why hibernate generates 1 delete per entity on a child table instead of using one delete on the foreign key

Here's the hibernate.cfg.xml (No i's not the next SO :-t

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.url">jdbc:hsqldb:file:testdb;shutdown=true</property>
        <property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password"></property>
        <property name="hibernate.connection.pool_size">0</property>
        <property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hbm2ddl.auto">auto</property>
        <mapping file="entities/Question.hbm.xml"/>
        <mapping file="entities/Answer.hbm.xml"/>

    </session-factory>

Question.hbm.xml

<hibernate-mapping>
   <class name="entities.Question">
      <id name="id">
         <generator class="native" />
      </id>
      <property name="title" not-null="true">
      </property>

      <property name="question" type="text" not-null="true">
      </property>

      <bag name="answers" inverse="true" cascade="all,delete-orphan" >
         <key>
            <column name="questionId" index="answer_questionId_idx" not-null="true"/>
         </key>
         <one-to-many class="entities.Answer"  />
      </bag>

      <property name="created" update="false" >
         <column name="created" not-null="true" index="answer_created_idx"></column>
      </property>
      <property name="lastUpdated">
         <column name="lastUpdated"  not-null="true" index="answer_lastUpdated_idx"></column>
      </property>
   </class>
</hibernate-mapping>

Answer.hbm.xml

<hibernate-mapping>
   <class name="entities.Answer">
      <id name="id">
         <generator class="native" />
      </id>

      <property name="answer" type="text" not-null="true">
      </property>

      <property name="created" update="false" >
            <column not-null="true" name="created" index="question_created_idx"></column>
      </property>

      <property name="lastUpdated" >
            <column name="lastUpdated" not-null="true" index="question_lastUpdated_idx"></column>
                  </property>

      <many-to-one  name="question" column="questionId" not-null="true" update="false">
      </many-to-one>
   </class>
</hibernate-mapping>

There's 1 Question and 2 answers in my database, this test code:

Session session = factory.openSession();
Transaction t = session.beginTransaction();
Question q = (Question) session.load(Question.class,1);
session.delete(q);
t.commit();
session.close();

I would expect it to generate SQL like,

select .... from Questions where id = 1;
delete from Answers where questionId=1;
delete from Question where id=1;

I.e., just issue one delete to do the cascading delete on Answers, instead it's loading all the answers and issuing one delete per answer, like:

select
    question0_.id as id0_0_,
    question0_.title as title0_0_,
    question0_.question as question0_0_,
    question0_.created as created0_0_,
    question0_.lastUpdated as lastUpda5_0_0_ 
from
    Question question0_ 
where
    question0_.id=?

select
    answers0_.questionId as questionId0_1_,
    answers0_.id as id1_,
    answers0_.id as id1_0_,
    answers0_.answer as answer1_0_,
    answers0_.created as created1_0_,
    answers0_.lastUpdated as lastUpda4_1_0_,
    answers0_.questionId as questionId1_0_ 
from
    Answer answers0_ 
where
    answers0_.questionId=?

delete   from   Answer  where     id=?
delete   from   Answer  where     id=?
delete   from   Question where     id=?

How come, and is there anything I can do about it ?

Edit, in response to Nate Zaugg, I can get the db to do the cascading delete by setting on-delete="cascade" on the one-to-many key mapping, i'm more wondering why hibernate does what it does and not does one delete on the Answers table, and wheter threre's something wrong with my mappings.

A: 

Can you not configure your DMBS to do cascading deletes on relationships? It's really easy to do.

Edit: Try this <one-to-many class="entities.Answer" lazy="false" cascade="all" />

Nate Zaugg
This doesn't answer the question.
Pascal Thivent
I believe it answered the "is there anything I can do about it" part! :)
Nate Zaugg