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 codemonkey <[EMAIL PROTECTED]>
>>
>> >> >>>> >>> >> >>> Is this possible in NH? I have googled forever and cannot
>> >> >>>> >>> >> >>> find
>> >> >>>> >>> >> >>> any
>> >> >>>> >>> >> >>> info at all? My only option it seems is to use a seperate
>> >> >>>> >>> >> >>> table
>> >> >>>> >>> >> >>> to
>> >> >>>> >>> >> >>> my
>> >> >>>> >>> >> >>> image and map using a one-to-one withlazyset tot true.
>>
>> >> >>>> >>> >> >>> Any advice would be good..
>>
>> >> >>>> >>> >> >>> Cheers
>> >> >>>> >>> >> >>> Stefan
>>
>> >> >>>> >>> >> >> --
>> >> >>>> >>> >> >> Fabio Maulo
>>
>> >> >>>> >>> >> > --
>> >> >>>> >>> >> > Stefan Sedich
>> >> >>>> >>> >> > Software Developer
>> >> >>>> >>> >> >http://weblogs.asp.net/stefansedich
>>
>> >> >>>> >>> >> --
>> >> >>>> >>> >> Stefan Sedich
>> >> >>>> >>> >> Software Developer
>> >> >>>> >>> >>http://weblogs.asp.net/stefansedich
>>
>> >> >>>> >>> > --
>> >> >>>> >>> > Tuna Toksöz
>>
>> >> >>>> >>> > Typos included to enhance the readers attention!
>>
>> >> >>>> >>> --
>> >> >>>> >>> Stefan Sedich
>> >> >>>> >>> Software Developer
>> >> >>>> >>>http://weblogs.asp.net/stefansedich
>>
>> >> >>>> >> --
>> >> >>>> >> Tuna Toksöz
>>
>> >> >>>> >> Typos included to enhance the readers attention!
>>
>> >> >>>> > --
>> >> >>>> > Stefan Sedich
>> >> >>>> > Software Developer
>> >> >>>> >http://weblogs.asp.net/stefansedich
>>
>> >> >>>> --
>> >> >>>> Stefan Sedich
>> >> >>>> Software Developer
>> >> >>>>http://weblogs.asp.net/stefansedich
>>
>> >> >>> --
>> >> >>> Tuna Toksöz
>>
>> >> >>> Typos included to enhance the readers attention!
>>
>> >> >> --
>> >> >> Stefan Sedich
>> >> >> Software Developer
>> >> >>http://weblogs.asp.net/stefansedich
>>
>> >> > --
>> >> > Stefan Sedich
>> >> > Software Developer
>> >> >http://weblogs.asp.net/stefansedich
>>
>> >> --
>> >> Stefan Sedich
>> >> Software Developer
>> >>http://weblogs.asp.net/stefansedich
>>
>> > --
>> > Fabio Maulo
>>
>> --
>> Stefan Sedich
>> Software Developerhttp://weblogs.asp.net/stefansedich
> >
>
--
Stefan Sedich
Software Developer
http://weblogs.asp.net/stefansedich
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---