-->
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.  [ 13 posts ] 
Author Message
 Post subject: Cascading delete on association table
PostPosted: Tue Aug 17, 2004 6:03 am 
Beginner
Beginner

Joined: Tue Aug 17, 2004 5:06 am
Posts: 46
My problem is a rather simple one:

I have two classes (A, C) that are linked by an association class B:

Code:
A <---- B ----> C
A 1:n B n:1 C

I do:
A --- B --- C
A --- B
and expected that B is deleted as well.


I want the following:
If A or C ist deleted, then B should be deleted as well. No matter if B is still linked to another A or C. This is just a normal cascading delete.

I mapped the sets in A and C with cascase="all-delete-orphan". However it seems that B is not deleted when it's still linked to another object.
So I tried cascade="all", but that didn't change a thing.

Hibernate version: 2.1.4

Mapping documents:

Object A:
Code:
<hibernate-mapping>
    <class
        name="com.bawag.fi.model.hibernate.CompanyRepresentativeHPB"
        table="company_representative"
        dynamic-update="false"
        dynamic-insert="false"
        discriminator-value="COMPREPR"
    >
...
        <set
            name="invitations"
            lazy="true"
            inverse="true"
            cascade="all-delete-orphan"
            sort="unsorted"
        >

              <key
                  column="fk_company_representative"
              >
              </key>

              <one-to-many
                  class="com.bawag.fi.model.hibernate.EventInvitationHPB"
              />
        </set>
</hibernate-mapping>


Object C:
Code:
<hibernate-mapping>
    <class
        name="com.bawag.fi.model.hibernate.EventHPB"
        table="event"
        dynamic-update="false"
        dynamic-insert="false"
        discriminator-value="EVENT"
    >
...
        <set
            name="invitations"
            lazy="true"
            inverse="true"
            cascade="all-delete-orphan"
            sort="unsorted"
        >

              <key
                  column="fk_event"
              >
              </key>

              <one-to-many
                  class="com.bawag.fi.model.hibernate.EventInvitationHPB"
              />
        </set>


Object B (association object):
Code:
<hibernate-mapping>
    <class
        name="com.bawag.fi.model.hibernate.EventInvitationHPB"
        table="event_invitation"
        dynamic-update="false"
        dynamic-insert="false"
        discriminator-value="EVENTINV"
    >
...
        <many-to-one
            name="companyRepresentative"
            class="com.bawag.fi.model.hibernate.CompanyRepresentativeHPB"
            cascade="all"
            outer-join="auto"
            update="true"
            insert="true"
            access="property"
            foreign-key="fk_CR_EI_company_representati"
            column="fk_company_representative"
        />

        <many-to-one
            name="event"
            class="com.bawag.fi.model.hibernate.EventHPB"
            cascade="all"
            outer-join="auto"
            update="true"
            insert="true"
            access="property"
            foreign-key="fk_E_EI_event"
            column="fk_event"
        />


Code between sessionFactory.openSession() and session.close():
Code:
tx = session.beginTransaction();
// delete the object
session.delete(aCompanyRepresentative);
tx.commit();


Full stack trace of any exception that occurs:
[code]
Hibernate: select fromrelati0_.id as id__, fromrelati0_.fk_from_company as fk_from_3___, fromrelati0_.id as id0_, fromrelati0_.SUBTYPE as SUBTYPE0_, fromrelati0_.fk_from_company as fk_from_3_0_, fromrelati0_.fk_to_company as fk_to_co4_0_, fromrelati0_.ownershipRatio as ownershi5_0_ from fi.company_relationship fromrelati0_ where fromrelati0_.fk_from_company=?
11:18:38,935 DEBUG LongType:46 - binding '53' to parameter: 1
Hibernate: select torelation0_.id as id__, torelation0_.fk_to_company as fk_to_co4___, torelation0_.id as id0_, torelation0_.SUBTYPE as SUBTYPE0_, torelation0_.fk_from_company as fk_from_3_0_, torelation0_.fk_to_company as fk_to_co4_0_, torelation0_.ownershipRatio as ownershi5_0_ from fi.company_relationship torelation0_ where torelation0_.fk_to_company=?
11:18:38,951 DEBUG LongType:46 - binding '53' to parameter: 1
Hibernate: select visits0_.id as id__, visits0_.fk_company as fk_company__, visits0_.id as id0_, visits0_.location as location0_, visits0_.timestamp as timestamp0_, visits0_.lunch as lunch0_, visits0_.employeeName1 as employee5_0_, visits0_.employeeName2 as employee6_0_, visits0_.employeeName3 as employee7_0_, visits0_.employeeName4 as employee8_0_, visits0_.employeeName5 as employee9_0_, visits0_.employeeName6 as employe10_0_, visits0_.employeeName7 as employe11_0_, visits0_.employeeName8 as employe12_0_, visits0_.employeeName9 as employe13_0_, visits0_.employeeName10 as employe14_0_, visits0_.companyRepresentativeName1 as company15_0_, visits0_.companyRepresentativeName2 as company16_0_, visits0_.companyRepresentativeName3 as company17_0_, visits0_.companyRepresentativeName4 as company18_0_, visits0_.companyRepresentativeName5 as company19_0_, visits0_.companyRepresentativeName6 as company20_0_, visits0_.companyRepresentativeName7 as company21_0_, visits0_.companyRepresentativeName8 as company22_0_, visits0_.companyRepresentativeName9 as company23_0_, visits0_.companyRepresentativeName10 as company24_0_, visits0_.fk_company as fk_company0_ from fi.visit visits0_ where visits0_.fk_company=?
11:18:38,967 DEBUG LongType:46 - binding '53' to parameter: 1
Hibernate: select invitation0_.id as id__, invitation0_.fk_company_representative as fk_compa2___, invitation0_.id as id0_, invitation0_.fk_company_representative as fk_compa2_0_, invitation0_.fk_event as fk_event0_ from fi.event_invitation invitation0_ where invitation0_.fk_company_representative=?
11:18:38,982 DEBUG LongType:46 - binding '103' to parameter: 1
11:18:38,998 DEBUG LongType:68 - returning '133' as column: id0_
11:18:38,998 DEBUG LongType:68 - returning '103' as column: fk_compa2_0_
11:18:39,014 DEBUG LongType:68 - returning '125' as column: fk_event0_
11:18:39,014 DEBUG LongType:68 - returning '103' as column: fk_compa2___
11:18:39,014 DEBUG LongType:68 - returning '133' as column: id__
Hibernate: select eventhpb0_.id as id0_, eventhpb0_.name as name0_, eventhpb0_.beginDate as beginDate0_, eventhpb0_.endDate as endDate0_, eventhpb0_.remarks as remarks0_ from fi.event eventhpb0_ where eventhpb0_.id=?
11:18:39,029 DEBUG LongType:46 - binding '125' to parameter: 1
11:18:39,045 DEBUG StringType:68 - returning 'BAWAG Management Cercle' as column: name0_
11:18:39,060 DEBUG DateType:68 - returning '17 August 2004' as column: beginDate0_
11:18:39,076 DEBUG DateType:68 - returning '17 August 2004' as column: endDate0_
11:18:39,092 DEBUG StringType:68 - returning 'J


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 17, 2004 7:54 am 
Expert
Expert

Joined: Fri Feb 06, 2004 7:49 am
Posts: 255
Location: Moscow, Russia
I cannot read in your native language ;) but It is database constraint violation:

ORA-02292: Versto

_________________
Leonid Shlyapnikov


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 17, 2004 8:06 am 
Beginner
Beginner

Joined: Tue Aug 17, 2004 5:06 am
Posts: 46
Quote:
but It is database constraint violation.
If you want your cascade delete scenario works, your database constraints should permit it. Check this constraint FI.FK_CR_EI_COMPANY_REPRESENTATI and consult your DBA or a guy that modeled the database schema. I think he added this constraint with some thoughts about data integrity.


I know that it's a database constraint violation. The constraint itself makes absolute sense.

The problem is that the cascading delete doesn't work, i.e. it doesn't delete the child record if the child record still has a relation to another parent record.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 17, 2004 8:55 am 
Expert
Expert

Joined: Fri Feb 06, 2004 7:49 am
Posts: 255
Location: Moscow, Russia
Well...
In "Hibernate In Action" and in the reference documentation I have not seen that parent and child have cascade association to each other.

E.g. parent has inverse="true" cascade="all-delete-orphan" collection, child has cascade="none" many-to-one association to parent (Chapter 3 of HIA, Bid and Item example). In you case child has cascade="all" many-to-one associations to both parent objects. I am not sure if it works by design. So make it simple, replace cascade="all" by cascade="none" for many-to-one assocs in your child and try to handle cascade delete manually.

_________________
Leonid Shlyapnikov


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 17, 2004 9:05 am 
Beginner
Beginner

Joined: Tue Aug 17, 2004 5:06 am
Posts: 46
Oh, I forgot to remove the cascade="all" from the child mapping.

It wasn't there when I tried it for the first time. However, if I change it to cascade="none" things don't change. I still get the same constraint violation.

Regarding your approach with natural db cascading deletes: this would work, but then I have an inconsistent Hibernate cache. I really don't want to mix the persistence mechanisms.

I still think that it must be possible to do a cascading delete with Hibernate in the way that a database would do it. It's just a mapping detail that I can't find...


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 17, 2004 9:16 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
(1) Make sure you only have cascade="all" on the one-to-many associations
(2) Make sure that objects to be deleted don't get resaved by cascade save! So remove them from other associations that they belong to.
(3) Use Hibernate's log to find the source of your problems.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 17, 2004 9:17 am 
Expert
Expert

Joined: Fri Feb 06, 2004 7:49 am
Posts: 255
Location: Moscow, Russia
Code:
Parent1 ---------------> Child ----------------------->Parent2
    cascade="all-delete-orphan"
                                                      cascade="none"

you delete Parent1 using session.delete(parent1); it deletes all dependent children (but Child-to-Parent2 is mapped with cascade="none" ==> and Parent2 will not be deleted and you will get database constraint violation).

Quote:
Regarding your approach with natural db cascading deletes: this would work, but then I have an inconsistent Hibernate cache. I really don't want to mix the persistence mechanisms.

Session.clear(); SessionFactory.clear() should help you.

And you could handle cascade deletes not only with low-level JDBC calls, for example you can call session.delete() for all dependent objects and then delete their parent. But you know, it is better to implement batch updates/deletes using low-level JDBC calls.

_________________
Leonid Shlyapnikov


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 17, 2004 9:19 am 
Expert
Expert

Joined: Fri Feb 06, 2004 7:49 am
Posts: 255
Location: Moscow, Russia
There is not SessionFactory.clear() in Hibernate API, so use SessionFactory.evict(Class).

_________________
Leonid Shlyapnikov


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 17, 2004 9:22 am 
Expert
Expert

Joined: Fri Feb 06, 2004 7:49 am
Posts: 255
Location: Moscow, Russia
Think Gavin knows more... ;)

_________________
Leonid Shlyapnikov


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 17, 2004 9:29 am 
Beginner
Beginner

Joined: Tue Aug 17, 2004 5:06 am
Posts: 46
Code:
Parent1 ----- Child ----- Parent2


I don't want Parent2 be deleted when I delete Parent1. I just want Parent1 and Child being deleted.
If I add cascade="all" to the many-to-on association between Child and Parent2, then the Parent2 gets deleted as well.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 17, 2004 9:55 am 
Beginner
Beginner

Joined: Tue Aug 17, 2004 5:06 am
Posts: 46
I found the problem:

The root object has been retrieved in another session. Once I refresh it before the delete everything works fine.

Except that my database load has tripled...


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 17, 2004 9:57 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
refresh??

shouldn't you be using lock() to perform reassociation?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 17, 2004 10:13 am 
Beginner
Beginner

Joined: Tue Aug 17, 2004 5:06 am
Posts: 46
I tried, but its rather complex. The root object has many associated objects. I just can't lock all of them. Refresh worked...

I'm afraid that I used Hibernate in the wrong way in my web application. I wanted to stay stateless and opened/closed the session for every request. This approach has resulted in many problems.

On the other hand: If I put the session into the session scope I'll have half my database in the session cache. This won't scale well...

I think I'll have to re-read the session, transaction and isolation chapter...


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 13 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.