-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: Child delete
PostPosted: Mon Mar 28, 2005 9:03 pm 
Newbie

Joined: Mon Mar 28, 2005 8:44 pm
Posts: 2
Hi,

I am having a Hibernate For Dummies problem with a parent -> child relationship deleting the children when I delete the parent. My understanding is that if I specify cascade="all-delete-orphan" that dereferenced children will be deleted. But, I assume that if I delete the parent entity via a call to session.delete(parent) that SQL deletes would be generated for ALL the children in the collection.

That is not happening. I call delete on the parent and the child row is still present in the database.

I am doing this with a detached object, but I don't think that's the core of the problem. Here is my unit test (patient is the parent class, appointment is the child class):

Code:
    public void testAddAppointmentDetached() {
        dao.savePatient(patient);
        Patient retrievedPatient = dao.retrievePatientByUserName("Patient1");
        retrievedPatient.addAppointment(createAppointment());
        dao.savePatient(retrievedPatient);
        retrievedPatient = dao.retrievePatientByUserName("Patient1");
        assertEquals(1, retrievedPatient.getUpcomingAppointmentsCount());
        dao.removePatient(patient);
    }


This test passes, but to my surprise the dao.removePatient (see code below) is leaving an orphan row in the database. I have even tried adding an explicit line in my DAO to reset the collection of appointments (which shouldn't be necessary I wouldn't think, in the case of a parent deletion). but even that still doesn't delete the child appointment.

What blindingly obvious thing am I missing?

Hibernate version:2.1

Hibernate mapping documents
Code:
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
   <class name="demo.domain.Patient" table="Patient">
      <id name="id" column="PATIENT_ID">
         <generator class="increment" />
      </id>
      <property name="lastName" column="LAST_NAME" type="string" />
      <property name="firstName" column="FIRST_NAME" type="string" />
      <property name="middleNameOrInitial" column="MIDDLE_NAME"
         type="string" />
      <property name="birthDate" column="BIRTH_DATE" type="date" />
      <property name="age" column="AGE" type="integer" />
      <property name="socialSecurityNumber" column="SSN"
         type="string" />
      <property name="userName" column="USERNAME" type="string" />
      <property name="password" column="PASSWORD" type="string" />
      <set name="appointments" inverse="true" cascade="all-delete-orphan">
         <key column="PATIENT_ID"/>
         <one-to-many class="demo.domain.Appointment"/>
      </set>
   </class>
</hibernate-mapping>

<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
   <class name="demo.domain.Appointment" table="Appointment">
      <id name="id" column="APPOINTMENT_ID">
         <generator class="increment" />
      </id>
      <property name="time" column="TIME" type="string" />
      <property name="clinic" column="CLINIC" type="string" />
      <property name="doctor" column="DOCTOR" type="string" />
      <property name="appointmentDate" column="APPOINTMENT_DATE" type="date" />
      <many-to-one name="patient" column="PATIENT_ID" class="demo.domain.Patient" not-null="true"/>
   </class>
</hibernate-mapping>

Code between sessionFactory.openSession() and session.close():
Code:
        patient.getAppointments().clear();
        session.delete(patient);



Name and version of the database you are using: MySQL 4.1

The generated SQL (show_sql=true):

18:27:14,688 INFO SessionFactoryImpl:119 - building session factory
18:27:14,688 INFO ReflectHelper:186 - reflection optimizer disabled for: demo.domain.Patient, BulkBeanException: Property is private (property setAppointments)
18:27:14,708 INFO SessionFactoryObjectFactory:82 - Not binding factory to JNDI, no JNDI name configured
Hibernate: delete from Patient where PATIENT_ID=?


Debug level Hibernate log excerpt:


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 30, 2005 12:40 am 
Newbie

Joined: Mon Mar 28, 2005 8:44 pm
Posts: 2
Anyone?

I read through the applicable chapters in the 2.1 manual again - still don't see what I'm missing. A key excerpt below. Tomorrow I will try a test where I do the delete on the parent in the same session as it was originally retrieved, without changing any of the hibernate mapping files, and see if it works (in other words, if my problem lies somehow with the use of the detached object).

From manual:
A child which becomes unreferenced by its parent is not automatically deleted, except in the case of a <one-to-many> association mapped with cascade="all-delete-orphan". The precise semantics of cascading operations are as follows:
    If a parent is saved, all children are passed to saveOrUpdate()

    If a parent is passed to update() or saveOrUpdate(), all children are passed to saveOrUpdate()

    If a transient child becomes referenced by a persistent parent, it is passed to saveOrUpdate()

    If a parent is deleted, all children are passed to delete()

    If a transient child is dereferenced by a persistent parent, nothing special happens (the application should explicitly delete the child if necessary) unless cascade="all-delete-orphan", in which case the "orphaned" child is deleted.



Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 30, 2005 7:10 pm 
Regular
Regular

Joined: Thu Apr 15, 2004 1:12 pm
Posts: 55
Hi,

I believe this is the behavior that would result if your Patient.createAppointment() method only set the 'patient' property of the new Appointment, without also adding the new Appointment to the 'appointments' Set property of the Patient.

Can you check your createAppointment() method, and make sure it actually adds the new appointment to the Patient's set?

—ml—


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.