[ajug-members] Order of cascaded deletes with hibernate
Roy Wells
roy.g.wells at gmail.com
Thu Apr 28 11:08:04 EDT 2005
Its not really buisness logic. I simply want to delete all children
of object A. From the business side of things I don't care what order
they are deleted in, except for the fact that it causes a constraint
violation if you do it in the wrong order.
In principal all the data needed to figure out the proper order is in
the Mapping document. You simply have to look for any many-to-ones
flagged not null and if both sides of that are flagged for delete
during a cascade then make sure you delete the many side first. Maybe
this should be a jira issue. Then again those extra checks might be
hard on performance for an edge case. Though its a little frustrating
to have to break from Hibernates typical paradigm of simply deleteing
the object and letting it cascade in this one case.
In any case thank you for the response. Its nice to see someone out
there is willing to answer hibernate questions.
While I'm at it, can I trouble you with one more?
Is it possible to initialize a 3 level or deeper hierarchy of objects
with out doing an n+1 select.
Here is the example.
Class "A" has a one-to-many relation with class "B" which has a
one-to-many relation with class "C". A--*B--*C.
If I wanted to load A with its B collection initialized that is as
simple as "from A a left join fetch a.bList". However I want to load
A with the B collection initialized and all of the B's C collections
initialized. Is that possible?
Thanks again for the help
Roy Wells.
On 4/27/05, Les A. Hazlewood <les at hazlewood.com> wrote:
>
> As a former Hibernate consultant (worked w/ Gavin, Steve, et. al), I'll
> answer ;)
>
> Hibernate does not support allowing you to control the order of cascade
> execution.
>
> Hibernate uses transactional write-behind algorithms for determining
> which objects it needs to insert/update/delete and when. This basically
> means that it optimizes the order in which SQL statements are executed
> automagically at the end of a transaction based on a number of things,
> including dirty data, collection modification, etc.
>
> Because Hibernate uses these optimization algos, it determines how
> cascades will be executed, not the programmer. This is the primary
> reason why Hibernate is almost always faster than a comparable
> appliation that uses hand-written JDBC calls. It can do all sorts of
> things like use the JDBC batch api, only execute sql upon transaction
> commit, etc., all transparently to the programmer while increasing
> performance.
>
> However, because you need certain elements to be deleted before others,
> this might be a red flag that what you require is more closely related
> to business logic (your app requirements) and not raw persistence logic
> (Hibernate's realm). If this is the case, explicit manual deletion is
> usually preferred since it will be obviously documented in your source
> code, thereby clearly reflecting your application requirements.
>
> Best regards,
>
> Les
>
> On Wed, 27 Apr 2005 12:30:17 -0400, "Roy Wells" <roy.g.wells at gmail.com>
> said:
> > To any hibernate gurus out there.
> >
> > I'm having an issue with cascaded deletes in hibernate. I would ask
> > this on the hibernate forum but that place gives answers at a snails
> > pace. In fact someone else allready asked it there and got ignored.
> >
> > Here is the setup: Class "A" is a parent to both "B" and "C", and has
> > one-to-many collections of each. Class "C" has a unidirectional
> > many-to-one association with "B". The one-to-many collections from
> > "A" to both "B" and "C" are cascade delete.
> >
> > The problem arrises when hibernate triggers cascade deletes from "A"
> > to "B" and "C" it needs to delete "C" first but it doesn't.
> >
> > Is there a way to control the order in which deletes are cascaded in
> > hibernate. Otherwise I guess i'll just turn off the cascade deletes
> > and handle it with manual calls.
> >
> > I also thought I might solve this with a Hibernate Interceptor, but
> > i've read that calling back into the session and triggering additional
> > operations from a hibernate interceptor is not supported.
> >
> > Here is what the hibernate mapping essentially looks like.
> >
> > <hibernate-mapping >
> >
> > <class name="A">
> > <id name="id"><generator class="native" /></id>
> > <bag name="bList inverse="true" lazy="true" cascade="all">
> > <key column="a_id"/>
> > <one-to-many class="B"/>
> > </bag>
> > <bag name="cList inverse="true" lazy="true" cascade="all">
> > <key column="a_id"/>
> > <one-to-many class="C"/>
> > </bag>
> > </class>
> >
> > <class name="B">
> > <id name="id"><generator class="native" /></id>
> > <many-to-one name="a" column="a_id" not-null="true"/>
> > </class>
> >
> > <class name="C">
> > <id name="id"><generator class="native" /></id>
> > <many-to-one name="a" column="a_id" not-null="true"/>
> > <many-to-one name="b" column="b_id" not-null="true"/>
> > </class>
> >
> > </hibernate-mapping>
> >
> > _______________________________________________
> > ajug-members mailing list
> > ajug-members at ajug.org
> > http://www.ajug.org/mailman/listinfo/ajug-members
>
More information about the ajug-members
mailing list