Yes, it is needed because cascade="none". It would be nice to have
cascade turned on, but then NH needs to know that the blob entities
really points to the same table row as its parent. I couldn't find a
way to do that. If cascade="save-update", NH will try to do an 3
inserts, one for the parent entity and one for each blob, instead of 1
insert and 2 updates.

I should point out though that I have only been using NH for about a
month so any help is appreciated.

Regards,
Johannes

On 17 Nov, 10:38, "Stefan Sedich" <[EMAIL PROTECTED]> wrote:
> Interesting solution, do you need the second update
> session.Update(inv.XmlData1);?
>
> I guess that is one thing that would put me off this solution.
>
> Apart from that it looks interesting.
>
> Cheers
> Stefan
>
> On Mon, Nov 17, 2008 at 4:38 PM, Johannes <[EMAIL PROTECTED]> wrote:
>
> > I have been playing around trying to get mapping of 2 classes to 1
> > table in order to get lazy loading properties to work. I thought i'd
> > share it here. I posted a previous example but I have made som
> > improvements since. Before, I had to use a ISession.Refresh() between
> > inserting the first row to db and then update the blob field. This is
> > no longer neccesary. Let's start with an example:
>
> > I have a legacy database with a table called Invoice. It has 2 blobs
> > that contains xml data.
>
> > create table Invoice
> > (
> >  InvoiceId int not null primary key,
> >  InvoiceNo varchar(30),
> >  CustomerName varchar(50),
> >  XmlData1 varbinary(max),
> >  XmlData2 varbinary(max)
> > )
>
> > What I had to do was to create 3 entity classes, 1 for the main
> > Invoice and 1 for each field that I want to lazy load:
>
> > public class Invoice
> > {
> >  public int InvoiceId { get; set; }
> >  public string InvoiceNo { get; set; }
> >  public string CustomerName { get; set; }
> >  public InvoiceXmlData1 XmlData1 { get; set; }
> >  public InvoiceXmlData2 XmlData2 { get; set; }
>
> >  Invoice()
> >  {
> >    XmlData1 = new InvoiceXmlData1();
> >    XmlData2 = new InvoiceXmlData2();
> >  }
> > }
>
> > public class InvoiceData
> > {
> >  public int InvoiceId { get; set; }
> >  public byte[] Data { get; set; }
> > }
>
> > public class InvoiceXmlData1 : InvoiceData
> > {
> > }
>
> > public class InvoiceXmlData2 : InvoiceData
> > {
> > }
>
> > The reason that I made one class per property is for the mapping to
> > work. The mapping looks like this:
>
> > <?xml version="1.0" encoding="utf-8" ?>
> > <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-
> > lazy="true" assembly="Domain" namespace="Domain">
> >  <class name="Invoice" table="Invoice">
> >    <id name="InvoiceId">
> >      <generator class="native"></generator>
> >    </id>
>
> >    <property name="InvoiceNo" not-null="true"></property>
> >    <property name="CustomerName" not-null="false"></property>
>
> >    <many-to-one name="XmlData1" column="InvoiceId" unique="true"
> > insert="false" update="false" cascade="none"></many-to-one>
> >    <many-to-one name="XmlData2" column="InvoiceId" unique="true"
> > insert="false" update="false" cascade="none"></many-to-one>
> >  </class>
>
> >  <class name="InvoiceXmlData1" table="Invoice" >
> >    <id name="InvoiceId">
> >      <generator class="foreign">
> >        <param name="property">Invoice</param>
> >      </generator>
> >    </id>
>
> >    <property name="Data" column="XmlData1"></property>
> >  </class>
>
> >  <class name="InvoiceXmlData2" table="Invoice">
> >    <id name="InvoiceId">
> >      <generator class="foreign">
> >        <param name="property">Invoice</param>
> >      </generator>
> >    </id>
>
> >    <property name="Data" column="XmlData2"></property>
> >  </class>
> > </hibernate-mapping>
>
> > Note cascade="none". cascade="save-update" would result i 2 inserts to
> > the same table. Also the attributes insert and update is set to
> > "false". I got IndexOutOfRangeException without these.
>
> > The code to insert:
>
> > Invoice inv = new Invoice();
> > inv.InvoiceNo = "12312";
> > inv.CustomerName = "The Customer";
> > inv.XmlData1.Data = new byte { 0x1, 0x2 };
>
> > session.Save(inv);
>
> > // assign newly created primary key to blob entities
> > inv.XmlData1.InvoiceId = inv.InvoiceId;
> > inv.XmlData2.InvoiceId = inv.InvoiceId;
>
> > // if data is null, only attach entity (small optimization, I think)
> > if (inv.XmlData1.Data == null)
> >  session.Lock(inv.XmlData1, LockMode.None);
> > else
> >  session.Update(inv.XmlData1);
>
> > if (inv.XmlData2.Data == null)
> >  session.Lock(inv.XmlData2, LockMode.None);
> > else
> >  session.Update(inv.XmlData2);
>
> > session.Flush();
>
> > updates works as usual:
>
> > Invoice inv = session.Get<Invoice>(...);
> > inv.XmlData1.Data = new byte { 0x2, 0x3 };
>
> > session.Flush();
>
> > Although I haven't tried deletes, but since cascade="none" it should
> > work. Just don't reference the blob entities after you deleted the
> > main entity. Maybe you need to do session.Evict(inv.XmlData1) to clear
> > the first level cache.
>
> > Comments?
>
> > Regards,
> > Johannes
>
> > On 14 Nov, 06:11, "Stefan Sedich" <[EMAIL PROTECTED]> wrote:
> >> No worries thanks Fabio, I still feel like an idiot for posting a
> >> wrong solution but hey I am only human :).
>
> >> Cheers
> >> Stefan
>
> >> On Fri, Nov 14, 2008 at 12:11 PM, Fabio Maulo <[EMAIL PROTECTED]> wrote:
> >> > Hi Stefan.
> >> > Thanks for the wiki in NHForge.
> >> > Only a note for who want write a wiki...
> >> > You can use WLW in your PC  and than copy&paste the HTML.
> >> > 2008/11/13 Stefan Sedich <[EMAIL PROTECTED]>
>
> >> >> Back to a unique foreign key mapping with a many to one to get this to
> >> >> work :\, what I originally had but insisted on the one to one, this
> >> >> works fine.
>
> >> >> Updated my posts to reflect my failure :). Key for next time MAKE SURE
> >> >> I RUN ALL MY TESTS FIRST!!!
>
> >> >> Cheers
>
> >> >> On Fri, Nov 14, 2008 at 9:24 AM, Stefan Sedich <[EMAIL PROTECTED]>
> >> >> wrote:
> >> >> > Looks like this is an EPIC fail, inserts seem not to work :\, I
> >> >> > thought I had tried this but when I got to work this morning and re
> >> >> > ran my rest:
>
> >> >> > NHibernate.Id.IdentifierGenerationException: null id generated
> >> >> > for:NHibernateDocumentTest.DocumentFile
>
> >> >> > Looks like it is back to the drawing board.
>
> >> >> > Fun fun fun
>
> >> >> > On Thu, Nov 13, 2008 at 10:04 PM, Stefan Sedich
> >> >> > <[EMAIL PROTECTED]> wrote:
> >> >> >> Not a problem glad my heart ache might help someone in the future,
> >> >> >> look forward to contributing more.
>
> >> >> >> Cheers
>
> >> >> >> On Thu, Nov 13, 2008 at 10:00 PM, Tuna Toksöz <[EMAIL PROTECTED]>
> >> >> >> wrote:
> >> >> >>> Thanks, Stefan! We really appreciate your help on blogging.
>
> >> >> >>> On Thu, Nov 13, 2008 at 2:58 PM, Stefan Sedich
> >> >> >>> <[EMAIL PROTECTED]>
> >> >> >>> wrote:
>
> >> >> >>>> Ok whipped this one up just then :), hopefully it makes sense to
> >> >> >>>> someone
> >> >> >>>> else.
>
> >> >> >>>>http://weblogs.asp.net/stefansedich/archive/2008/11/13/lazy-loaded-on...
>
> >> >> >>>> Cheers
>
> >> >> >>>> On Thu, Nov 13, 2008 at 9:46 PM, Stefan Sedich
> >> >> >>>> <[EMAIL PROTECTED]>
> >> >> >>>> wrote:
> >> >> >>>> > Yep will be blogging about this tonight :), hopefully save 
> >> >> >>>> > someone
> >> >> >>>> > else some frustration. Infact I will do it right away.
>
> >> >> >>>> > On Thu, Nov 13, 2008 at 9:45 PM, Tuna Toksöz <[EMAIL PROTECTED]>
> >> >> >>>> > wrote:
> >> >> >>>> >> A post from you would be welcome ! :) hahaha :)
>
> >> >> >>>> >> On Thu, Nov 13, 2008 at 2:41 PM, Stefan Sedich
> >> >> >>>> >> <[EMAIL PROTECTED]>
> >> >> >>>> >> wrote:
>
> >> >> >>>> >>> Yep thanks Tuna the answer was there all along, supprised I 
> >> >> >>>> >>> only
> >> >> >>>> >>> found
> >> >> >>>> >>> this on 1 site :\ would have thought more people have
> >> >> >>>> >>> done/blogged
> >> >> >>>> >>> about this before.
>
> >> >> >>>> >>> Ohh well time for a beer.
>
> >> >> >>>> >>> Cheers
>
> >> >> >>>> >>> On Thu, Nov 13, 2008 at 9:38 PM, Tuna Toksöz <[EMAIL 
> >> >> >>>> >>> PROTECTED]>
> >> >> >>>> >>> wrote:
> >> >> >>>> >>> > From the forum, I see that
>
> >> >> >>>> >>> > But now imagine your B object may or may not have associated 
> >> >> >>>> >>> > C
> >> >> >>>> >>> > (constrained="false"). What should getCee() return when
> >> >> >>>> >>> > specific B
> >> >> >>>> >>> > does
> >> >> >>>> >>> > not
> >> >> >>>> >>> > have C? Null. But remember, Hibernate must set correct value 
> >> >> >>>> >>> > of
> >> >> >>>> >>> > "cee" at
> >> >> >>>> >>> > the
> >> >> >>>> >>> > moment it set B (because it does no know when someone will 
> >> >> >>>> >>> > call
> >> >> >>>> >>> > getCee()).
> >> >> >>>> >>> > Proxy does not help here because proxy itself in already
> >> >> >>>> >>> > non-null
> >> >> >>>> >>> > object.
>
> >> >> >>>> >>> > So the resume: if your B->C mapping is mandatory
> >> >> >>>> >>> > (constrainted=true),
> >> >> >>>> >>> > Hibernate will use proxy for C resulting inlazy
> >> >> >>>> >>> > initialization. But
> >> >> >>>> >>> > if
> >> >> >>>> >>> > you
> >> >> >>>> >>> > allow B without C, Hibernate just HAS TO check presence of C 
> >> >> >>>> >>> > at
> >> >> >>>> >>> > the
> >> >> >>>> >>> > moment
> >> >> >>>> >>> > it loads B. But a SELECT to check presence is just 
> >> >> >>>> >>> > inefficient
> >> >> >>>> >>> > because
> >> >> >>>> >>> > the
> >> >> >>>> >>> > same SELECT may not just check presence, but load entire
> >> >> >>>> >>> > object. So
> >> >> >>>> >>> >lazy
> >> >> >>>> >>> >loadinggoes away.
>
> >> >> >>>> >>> > On Thu, Nov 13, 2008 at 2:34 PM, Stefan Sedich
> >> >> >>>> >>> > <[EMAIL PROTECTED]>
> >> >> >>>> >>> > wrote:
>
> >> >> >>>> >>> >> Final try:
>
> >> >> >>>> >>> >> <one-to-one name="DocumentFile" cascade="all-delete-orphan"
> >> >> >>>> >>> >>lazy="proxy" constrained="true" />
>
> >> >> >>>> >>> >> WORKS!!! Why is this the case can anyone shed some light why
> >> >> >>>> >>> >> constrained="true" on the Document worked?
>
> >> >> >>>> >>> >> On Thu, Nov 13, 2008 at 9:28 PM, Stefan Sedich
> >> >> >>>> >>> >> <[EMAIL PROTECTED]>
> >> >> >>>> >>> >> wrote:
> >> >> >>>> >>> >> > Arggggggggggg I was wrong this does not work. Seriously 
> >> >> >>>> >>> >> > if I
> >> >> >>>> >>> >> > could
> >> >> >>>> >>> >> > throw NH out the window right now I would hehe. :\
>
> >> >> >>>> >>> >> > On Thu, Nov 13, 2008 at 9:25 PM, Fabio Maulo
> >> >> >>>> >>> >> > <[EMAIL PROTECTED]>
> >> >> >>>> >>> >> > wrote:
> >> >> >>>> >>> >> >> property lazynees is not supported in NH basically 
> >> >> >>>> >>> >> >> because
> >> >> >>>> >>> >> >> we
> >> >> >>>> >>> >> >> need
> >> >> >>>> >>> >> >> FieldInterceptors (AFIK not experimented in .NET)
>
> >> >> >>>> >>> >> >> 2008/11/13
>
> ...
>
> läs mer »
--~--~---------~--~----~------------~-------~--~----~
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