so.. in a property getter you are accessing to a Relationship loaded using lazy-loading, inside the same class... and all to have a unnormalized property.interesting and discouraged approach.
Inside the getter you should check if "state" is a proxy and in that case you should initialize it (the dyn-proxy don't work inside the instance) Another possibility is fetch="join" to load "state" immediately. Your existing code are working only under some very specific condition: it work only if you access to the property "State" before access to the property "Num" from some place outside the class instance. To be clear, try this in a fresh session: var c = session.Get<Cat>(id); Assert.That(c.Num, Is.Not.EqualTo(0)); 2009/3/9 Germán Schuager <[email protected]> > My actual model is somewhat more complex than this: > > public interface INum > { > int Num { get; } > } > > public class Cat : Entity, INum > { > private State state; > > protected Cat() { } > > public Cat(State state) > { > this.state = state; > } > > public virtual State State { get { return state; } } > > public virtual int Num { get { return state.Num; } } > } > > <?xml version="1.0" encoding="utf-8"?> > <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="MyAssembly" > namespace="MyNamespace"> > <class name="Cat" table="Cats"> > <id name="ID" column="CatID" type="Int32"> > <generator class="hilo" /> > </id> > <many-to-one name="State" access="field.camelcase" /> > <property name="Num" access="readonly" /> > </class> > </hibernate-mapping> > > > On Mon, Mar 9, 2009 at 6:05 PM, Fabio Maulo <[email protected]> wrote: > >> Mapping please. >> >> >> 2009/3/9 Germán Schuager <[email protected]> >> >>> inline >>> >>> On Mon, Mar 9, 2009 at 5:11 PM, Fabio Maulo <[email protected]>wrote: >>> >>>> The fact is that the Merge need to read the state from DB but with its >>>> result in the persistent class (not from DataReader). >>> >>> >>> I think that I understand. That is the case of merging a detached entity, >>> but when merging a new transient entity that it is not in the DB then NH >>> does not need to do this, does it? >>> >>> >>>> BTW I don't understand how you can work with that entity... NH use the >>>> parameterless ctor not only for Merge but even when you use >>>> session.Get<T>(id). >>>> >>> >>> Yes, but when using session.Get, it creates the new entity and WRITE its >>> properties (*), on the other hand when using session.Merge it creates the >>> entity and READ its properties. >>> >>> >>>> In case of Get/Load who are injecting the State instance ? >>>> >>> >>> NH is assigning the state field. I don't understand what you mean. >>> >>> >>> >>> (*) here the problem could be that NH tries to set Num before State, but >>> this is due to me trying to simplify my domain; just suppose that Num >>> doesn't have a setter and is mapped using access="readonly" >>> >>> >>> >>>> >>>> >>>> 2009/3/9 Germán Schuager <[email protected]> >>>> >>>>> Thanks Fabio, I will take a look at what a tuplizer is :), but I don't >>>>> see why NH needs to access the properties of a newly created object just >>>>> to >>>>> overwrite them with the transient instance properties' values. >>>>> >>>>> I'm browsing the NH source to trying to find out but it is complex >>>>> beast... >>>>> >>>>> It seems that this drags from the fact that both EntityIsTransient and >>>>> EntityIsDetached are using the same method (CopyValues) to update the >>>>> properties of the resulting persistent entity. Do you see room for >>>>> improvement here or I should just move on? >>>>> >>>>> Thanks again. >>>>> >>>>> >>>>> On Mon, Mar 9, 2009 at 4:27 PM, Fabio Maulo <[email protected]>wrote: >>>>> >>>>>> Ah.. sorry.. in Merge sure it access to the getter... sorryIf you >>>>>> need a certain ctor you should implement your own tuplizer (I don't know >>>>>> where you will find the State instance but it is another matter). >>>>>> >>>>>> >>>>>> 2009/3/9 Germán Schuager <[email protected]> >>>>>> >>>>>>> I've tried it. It does access the getters when merging an entity in >>>>>>> the method CopyValues of DefaultMergeEventListener.cs >>>>>>> >>>>>>> >>>>>>> https://nhibernate.svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/src/NHibernate/Event/Default/DefaultMergeEventListener.cs >>>>>>> >>>>>>> >>>>>>> On Mon, Mar 9, 2009 at 3:14 PM, Fabio Maulo <[email protected]>wrote: >>>>>>> >>>>>>>> NH don't access to the getter during object creation. Try it. >>>>>>>> >>>>>>>> >>>>>>>> 2009/3/9 Germán Schuager <[email protected]> >>>>>>>> >>>>>>>>> Hi Fabio, >>>>>>>>> >>>>>>>>> Num is a persistent property, and I have several entities that >>>>>>>>> implement INum; in this case Cat is delegating its actual >>>>>>>>> implementation to >>>>>>>>> its private field "state". >>>>>>>>> >>>>>>>>> I don't think that a nosetter access for Num would solve the >>>>>>>>> problem because the exception would be generated anyway (when >>>>>>>>> accessing the >>>>>>>>> getter of Num for the newly instantiated Cat, the persistent one, >>>>>>>>> which has >>>>>>>>> state == null yet). >>>>>>>>> >>>>>>>>> And with the readonly accesor it would also be the same. >>>>>>>>> >>>>>>>>> The problem here is that NH is trying to read Num from an entity >>>>>>>>> that is in an invalid state in order to compare this value with the >>>>>>>>> transient one that I'm trying to merge, to determine if it should be >>>>>>>>> copied >>>>>>>>> or not. (At least I think this is the problem) >>>>>>>>> >>>>>>>>> Does this make sense? >>>>>>>>> >>>>>>>>> >>>>>>>>> On Mon, Mar 9, 2009 at 1:51 PM, Fabio Maulo >>>>>>>>> <[email protected]>wrote: >>>>>>>>> >>>>>>>>>> If Num is a persistent property you should use- a field only to >>>>>>>>>> make NH happy (you don't need to use it) >>>>>>>>>> - Num access="nosetter.camelcase"... if I well remember we have >>>>>>>>>> another accessor in NH2.1 access="read-only" >>>>>>>>>> >>>>>>>>>> 2009/3/9 Germán Schuager <[email protected]> >>>>>>>>>> >>>>>>>>>> Hi, >>>>>>>>>>> >>>>>>>>>>> I want to do a merge of a transient object which some of its >>>>>>>>>>> properties are assigned with detached objects, in order to get a >>>>>>>>>>> persistent >>>>>>>>>>> object with all its properties assigned with persistent instances >>>>>>>>>>> (using >>>>>>>>>>> cascade="merge"). Is this the correct usage scenario for merge? >>>>>>>>>>> >>>>>>>>>>> Here is a sample entity: >>>>>>>>>>> >>>>>>>>>>> public interface INum >>>>>>>>>>> { >>>>>>>>>>> int Num { get; } >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> public class Cat : Entity, INum >>>>>>>>>>> { >>>>>>>>>>> private State state; >>>>>>>>>>> >>>>>>>>>>> protected Cat() { } >>>>>>>>>>> >>>>>>>>>>> public Cat(State state) >>>>>>>>>>> { >>>>>>>>>>> this.state = state; >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> public State State { get { return state; } } <--- mapped >>>>>>>>>>> using access="field.camelcase" >>>>>>>>>>> >>>>>>>>>>> public int Num { >>>>>>>>>>> get { return state.Num; } >>>>>>>>>>> set { state.Num = value; } >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> The problem that I'm facing is that Merge is trying to read the >>>>>>>>>>> Num property from a Cat created using the protected constructor (the >>>>>>>>>>> persistent instance?) before assigning its "state" field, thus >>>>>>>>>>> throwing a >>>>>>>>>>> NullReferenceException in the getter. >>>>>>>>>>> >>>>>>>>>>> A simple solution would be to add a check to verify that state != >>>>>>>>>>> null in the getter, but that would be only to support NH >>>>>>>>>>> functionality and >>>>>>>>>>> it would have nothing to do with my domain. >>>>>>>>>>> >>>>>>>>>>> Do I need to add the check for state != null? >>>>>>>>>>> Can NH be improve to handle this situation? >>>>>>>>>>> >>>>>>>>>>> Regards. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Fabio Maulo >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Fabio Maulo >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Fabio Maulo >>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>>> >>>> >>>> >>>> -- >>>> Fabio Maulo >>>> >>>> >>>> >>> >>> >>> >> >> >> -- >> Fabio Maulo >> >> >> > > > > -- Fabio Maulo --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
