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

Reply via email to