think about an object graph with various soft-cascade setting ;)

On Fri, Aug 27, 2010 at 12:18 PM, nadav s <[email protected]> wrote:

> oh.
> actually, won't it actually be better that nhibernate will delete where
> father.id = :fatherId instead of each child getting a delete statement,
> when cascade is set to delete?
>
>
> On Fri, Aug 27, 2010 at 5:36 PM, MattO <[email protected]> wrote:
>
>> Okay, I see what on-delete cascade does at the database level.  This
>> assumes you put on cascading delete foreign keys on the database level
>> as well.  Guess I'll have to atleast make that change in order for
>> this to work (which I can do and is fairly minor).
>>
>> On Aug 27, 9:32 am, MattO <[email protected]> wrote:
>> > Also, I found the documentation on the on-delete option that appears
>> > to be missing from the nHibernate documentation here:
>> http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html
>> >
>> > It is only valid on <key> nodes though, not sure if you can add on-
>> > delete to key-property tags on a composite key.  I'm guessing not, so
>> > I may have to make some database changes and code changes.
>> >
>> > On Aug 27, 2:54 am, nadav s <[email protected]> wrote:
>> >
>> >
>> >
>> > > the simplest solution is instead of setting cascade delete, in the
>> > > DAO/Repository, when deleting the father entity, use an HQL delete
>> statement
>> > > on the children where their FatherId = the deleted father.
>> >
>> > > On Fri, Aug 27, 2010 at 9:45 AM, Frans Bouma <[email protected]> wrote:
>> > > > > there are 2 things I see that would cause this situation.
>> > > > > 1. you are using the native generator. this usually means the
>> database
>> > > > > controls the PK instead of the application. the downside to this
>> approach
>> > > > is
>> > > > > you loose the ability to batch CUD statements. I would strongly
>> recommend
>> > > > > switching to either guid.comb or hilo.
>> >
>> > > > > 2. if you have the cascade attribute set for the key of your
>> collections
>> > > > > it's set to noaction, which means the database will do nothing.
>> change
>> > > > this
>> > > > > to on-delete="cascade" and the database will delete them
>> automatically
>> > > > > (assuming the db has this feature). if the on-delete attribute
>> does not
>> > > > > exist, add it with the option to cascade.
>> > > > > this should fix the problem.
>> >
>> > > >        and assuming the entities aren't connected through multiple
>> paths :)
>> >
>> > > > > if the database does not support cascades, then NH must manage the
>> > > > deletes,
>> > > > > in which case option 1 above becomes very important. without
>> batching the
>> > > > > entities will be removed one at a time.
>> >
>> > > >        Doesn't NH support some kind of direct delete feature? I.e.
>> delete
>> > > > entities in bulk matching a given set of predicates? Which then
>> results in
>> > > > queries like DELETE FROM Foo WHERE ...
>> >
>> > > >        IMHO that should make MattO's problem go away instantly.
>> >
>> > > >                FB
>> >
>> > > > > On Aug 26, 6:50 pm, MattO <[email protected]> wrote:
>> > > > > > Okay, here they are (shortened).  Basically there is one
>> ContentCode
>> > > > > > (parent) to usually 300 to 400 ContentCodeDetails.
>> >
>> > > > > > Then for every user in the system that has access to the content
>> code
>> > > > > > details there could be up to 2000 to 4000 records for EACH user
>> in the
>> > > > > > ContentCodeAccess table.
>> >
>> > > > > > The problem is if I delete a parent, it deletes it with one
>> delete
>> > > > > > statement, then it deletes the 300 to 400 ContentCodeDetails
>> with 300
>> > > > > > to 400 DELETE statements, and finally it deletes the
>> ContentCodeAccess
>> > > > > > records with 2000 to 4000 delete statements.
>> >
>> > > > > > In my old ADO .NET code I did this in less than a second by
>> running 3
>> > > > > > delete statements.  Now it executes around 2500 to 4000 delete
>> > > > > > statements when I delete a parent record and takes 40 to 60
>> seconds.
>> >
>> > > > > > Here is the Parent (ContentCode):
>> >
>> > > > > >     <class name="ItemBankCoreNH.BusinessObjects.ContentCode,
>> > > > > > ItemBankCoreNH" table="[dbo].[ContentCodes]"
>> > > > > >            optimistic-lock="version" dynamic-update="true"
>> > > > > > lazy="true">
>> > > > > >         <id name="Id" column="[ContentCodeID]">
>> > > > > >             <generator class="native" />
>> > > > > >         </id>
>> > > > > >         <version name="TS" generated="always"
>> unsaved-value="null"
>> > > > > > type="BinaryBlob">
>> > > > > >             <!-- Generated="always" is to have database handle
>> > > > > > generation of timestamp -->
>> > > > > >             <column name="TS" not-null="false"
>> sql-type="timestamp"/>
>> > > > > >         </version>
>> > > > > >         ... More properties....
>> > > > > >         <bag name="ExamTypes" lazy="true" cascade="none">
>> > > > > >             <key column="[Type]" property-ref="ExamType" not-
>> > > > > > null="true" on-delete="noaction" update="false"></key>
>> > > > > >             <one-to-many class="ExamType" />
>> > > > > >         </bag>
>> > > > > >         <bag name="ContentCodeDetails" inverse="true"
>> cascade="all-
>> > > > > > delete-orphan" lazy="true">
>> > > > > >             <key not-null="true">
>> > > > > >                 <column name="[ContentCodeID]" sql-type="int" />
>> > > > > >             </key>
>> > > > > >             <one-to-many class="ContentCodeDetail" />
>> > > > > >         </bag>
>> > > > > >     </class>
>> >
>> > > > > > Here is the Child (ContentCodeDetails):
>> >
>> > > > > >     <class
>> name="ItemBankCoreNH.BusinessObjects.ContentCodeDetail,
>> > > > > > ItemBankCoreNH" table="[dbo].[ContentCodeDetail]"
>> > > > > >            optimistic-lock="version" dynamic-update="true"
>> > > > > > lazy="true">
>> > > > > >         <id name="Id" column="[ContentID]">
>> > > > > >             <generator class="native" />
>> > > > > >         </id>
>> > > > > >         <version name="TS" generated="always"
>> unsaved-value="null"
>> > > > > > type="BinaryBlob">
>> > > > > >             <!-- Generated="always" is to have database handle
>> > > > > > generation of timestamp -->
>> > > > > >             <column name="TS" not-null="false"
>> sql-type="timestamp"/>
>> > > > > >         </version>
>> > > > > >         <property name="ContentCodeID" column="[ContentCodeID]"
>> />
>> > > > > > .... More Properties...
>> > > > > >         <many-to-one name="ContentCodeParent"
>> class="ContentCode"
>> > > > > > insert="false" update="false" fetch="join">
>> > > > > >             <column name="[ContentCodeID]" sql-type="int" />
>> > > > > >         </many-to-one>
>> > > > > >         <bag name="ContentCodeAccessDetails"
>> cascade="all-delete-
>> > > > > > orphan" lazy="true">
>> > > > > >             <key not-null="true">
>> > > > > >                 <column name="[ContentID]" sql-type="int" />
>> > > > > >             </key>
>> > > > > >             <one-to-many class="ContentCodeAccess" />
>> > > > > >         </bag>
>> > > > > >     </class>
>> >
>> > > > > > And finally the table with the most records (ContentCodeAccess):
>> >
>> > > > > >     <class
>> name="ItemBankCoreNH.BusinessObjects.ContentCodeAccess,
>> > > > > > ItemBankCoreNH" table="[dbo].[ContentCodeAccess]"
>> > > > > >            optimistic-lock="version" dynamic-update="true"
>> > > > > > lazy="true">
>> > > > > >         <composite-id>
>> > > > > >             <key-property name="ContentID" column="[ContentID]"
>> />
>> > > > > >             <key-property name="DomainUser"
>> column="[DomainUser]" />
>> > > > > >             <key-property name="ExamType" column="[ExamType]" />
>> > > > > >             <key-property name="ContentCodeTypeID"
>> > > > > > column="[ContentCodeTypeID]" />
>> > > > > >         </composite-id>
>> > > > > >         <version name="TS" generated="always"
>> unsaved-value="null"
>> > > > > > type="BinaryBlob">
>> > > > > >             <!-- Generated="always" is to have database handle
>> > > > > > generation of timestamp -->
>> > > > > >             <column name="TS" not-null="false"
>> sql-type="timestamp"/>
>> > > > > >         </version>
>> > > > > >     </class>
>> >
>> > > > > > On Aug 26, 3:57 pm, Jason Meckley <[email protected]>
>> wrote:
>> >
>> > > > > > > inverse means the root entity is not responsible for the id of
>> child.
>> > > > > > > the child is itself an entity and will manage it's own POID.
>> >
>> > > > > > > What do you're mappings look like? I would assume you have
>> > > > > > > cascade="all" or all-delete-orphan. The strategies will use NH
>> to
>> > > > > > > manage the deletion rather than letting the database delete
>> child
>> > > > > > > relations through FK cascades.
>> >
>> > > > > > > if you set cascade="save-update" with the key as
>> on-delete="cascade"
>> > > > > > > the database should manage the deletion of related entities,
>> if it
>> > > > > > > supports cascade deletes. if it doesn't you can also look into
>> > > > > > > batching ADO.Net calls. This may not work depending on your
>> POID
>> > > > > > > strategy.
>> >
>> > > > > > > On Aug 26, 4:22 pm, MattO <[email protected]> wrote:
>> >
>> > > > > > > > How do you overcome the issue with nHibernate where
>> collections
>> > > > > > > > that are mapped with inverse="true" will be issued a delete
>> > > > > > > > statement for every object in the collection?
>> >
>> > > > > > > > Right now this has added about 50 seconds to a single delete
>> > > > > > > > operation which normally only took less than a second to
>> perform
>> > > > > > > > in straight ADO .NET by performing a delete based on the
>> primary
>> > > > > > > > key of the parent.
>> >
>> > > > > > > > According to the nHibernate reference manual section 17.5.4
>> (one
>> > > > > > > > shot delete), by discarding (dereferencing) the original
>> > > > > > > > collection and returning a newly instantiated collection
>> with all
>> > > > > > > > the current elements.
>> >
>> > > > > > > > Can someone please tell me what they mean with a code sample
>> if
>> > > > > > > > this also applys to inverse="true" collections, or is there
>> some
>> > > > > > > > other option other then manually handling deletes for these
>> types
>> > > > > > > > of collections yourself?- Hide quoted text -
>> >
>> > > > > > > - Show quoted text -
>> >
>> > > > > --
>> > > > > You received this message because you are subscribed to the Google
>> Groups
>> > > > > "nhusers" group.
>> > > > > To post to this group, send email to [email protected].
>> > > > > To unsubscribe from this group, send email to
>> > > > > [email protected]<nhusers%[email protected]>
>> <nhusers%[email protected]<nhusers%[email protected]>
>> ­­>
>> > > > .
>> > > > > For more options, visit this group at
>> > > > >http://groups.google.com/group/nhusers?hl=en.
>> >
>> > > > --
>> > > > You received this message because you are subscribed to the Google
>> Groups
>> > > > "nhusers" group.
>> > > > To post to this group, send email to [email protected].
>> > > > To unsubscribe from this group, send email to
>> > > > [email protected]<nhusers%[email protected]>
>> <nhusers%[email protected]<nhusers%[email protected]>
>> ­­>
>> > > > .
>> > > > For more options, visit this group at
>> >
>> > ...
>> >
>> > read more »- Hide quoted text -
>> >
>> > - Show quoted text -
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "nhusers" group.
>> To post to this group, send email to [email protected].
>> To unsubscribe from this group, send email to
>> [email protected]<nhusers%[email protected]>
>> .
>> For more options, visit this group at
>> http://groups.google.com/group/nhusers?hl=en.
>>
>>
>  --
> You received this message because you are subscribed to the Google Groups
> "nhusers" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected]<nhusers%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/nhusers?hl=en.
>



-- 
Fabio Maulo

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to