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]> > > . > > > 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.- 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]. For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.
