tag:blogger.com,1999:blog-32609450.post5471794717144170581..comments2023-09-15T13:14:58.827+01:00Comments on Colin Jack's Blog: NHibernate Gotchas - Orphans and one-to-oneColin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.comBlogger6125tag:blogger.com,1999:blog-32609450.post-23756124435629022542008-09-28T20:10:00.000+01:002008-09-28T20:10:00.000+01:00Not very nice but you could use a simply if-statem...Not very nice but you could use a simply if-statement to simply not execute the nhibernate delete statement if the object is just an in-memory object instead of a persistent one? Yes that is kind of a hack, but better than having to alter the mappings.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-32609450.post-89137274235003305772008-05-07T14:51:00.000+01:002008-05-07T14:51:00.000+01:00After spinning on this for a while, I thought I wo...After spinning on this for a while, I thought I would share my workaround:<BR/><BR/>Context: <BR/>* Registration has 1 Payment. <BR/>* A Payment could be a CreditCardPayment, CashPayment, MoneyOrderPayment or CheckPayment. <BR/>* A Payment has 1 Payee<BR/>* A Payee could be an IndividualPayee, OrganizationPayee, RegistrantPayee<BR/><BR/>So in the Registration mapping I have:<BR/><many-to-one class="Payment" column="[PaymentId]" name="payment" access="field" cascade="all-delete-orphan" lazy="false" fetch="join" /><BR/><BR/>in the Payment mapping I have:<BR/><one-to-one constrained="true" name="registration" access="field" property-ref="payment" /><BR/><many-to-one class="Payee" column="[PayeeId]" name="payee" access="field" cascade="all-delete-orphan" fetch="join" lazy="false" /><BR/><BR/>Ideally, I wanted to map Payment and Payee as components of a Registration, but as you know, there is no component inheritance in NHibernate.<BR/><BR/>My API works like this:<BR/>Registration r = new Registration());<BR/>r.Payment = new CashPayment();<BR/><BR/>In order to handle the orphans, I bascially had to create a query to get all of the existing "orphans" and then delete those.<BR/><BR/>//delete all payee orphans<BR/>Repository<Payee>.DeleteAll(new Query<Payee>(@"from Payee payee<BR/>where payee not in(select payment.payee from Payment payment where payment.payee is not null)"));<BR/> <BR/>//delete all payment orphans<BR/>Repository<Payment>.DeleteAll(new Query<Payment>(@"from Payment p <BR/>where p not in(select r.payment from Registration r where r.payment is not null)"));<BR/><BR/>Additionally, I had to first "save" my registration in its own transaction. Then run the "delete orphans" code its own transaction.<BR/><BR/>To bad the "all-delete-orphan" doesn't work for many-to-one or one-to-one mappings!Dennis Kozorahttps://www.blogger.com/profile/12972630423946444695noreply@blogger.comtag:blogger.com,1999:blog-32609450.post-42338338428180465852008-05-02T12:19:00.000+01:002008-05-02T12:19:00.000+01:00What did you ultimately do to as a workaround? The...What did you ultimately do to as a workaround? The only solution I can think of is to either first delete the child then save the entity or sync the child Id's. Ugh.Dennis Kozorahttps://www.blogger.com/profile/12972630423946444695noreply@blogger.comtag:blogger.com,1999:blog-32609450.post-75605237084765440192008-05-02T07:56:00.000+01:002008-05-02T07:56:00.000+01:00Afraid not, none of the solutions we found were pa...Afraid not, none of the solutions we found were particularly good...Colin Jackhttps://www.blogger.com/profile/01403166737046938219noreply@blogger.comtag:blogger.com,1999:blog-32609450.post-10762287852250644622008-05-02T00:22:00.000+01:002008-05-02T00:22:00.000+01:00Did you ever find a reasonable solution?Did you ever find a reasonable solution?Dennis Kozorahttps://www.blogger.com/profile/12972630423946444695noreply@blogger.comtag:blogger.com,1999:blog-32609450.post-32775461814022502192008-05-02T00:21:00.000+01:002008-05-02T00:21:00.000+01:00Did you ever find a reasonable solution?Did you ever find a reasonable solution?Dennis Kozorahttps://www.blogger.com/profile/12972630423946444695noreply@blogger.com