ah... The Versioning is not the place of the modification, instead, the
right place is the implementation of IVersionType inside Int32Type.
btw... a IUserVersionType would be perfect for your case.

On Wed, Nov 17, 2010 at 3:44 PM, Fabio Maulo <[email protected]> wrote:

> The implementation of a custom type is not an overkill, instead it is just
> the way NH gives you to define what is correct/intelligent for you.
> For me Int32 is more than enough and its default "unsaved-value" as zero is
> more than enough. You are looking for a version with two possible
> unsaved-value ('null' and zero)
>
> On Tue, Nov 16, 2010 at 9:14 PM, Mike Pontillo <[email protected]> wrote:
>
>> Hi Fabio,
>>
>>   Thanks for the response. A custom type seemed like overkill here
>> since all I really want is a nullable Int32. I ended up doing three
>> things to work around this problem:
>>
>>  - Made the version property in my POCO nullable (int?) to solve the
>> problem where NHibernate found a "dirty" (but not really dirty) object
>> in the database, since its version property was mistakenly set to null
>>  - Made the version property in my mapping XML just an "int" (not sure
>> if it necessary to call out that it's nullable in the mapping XML, but
>> I got the exception noted below when I did -- it works when I leave
>> out the type as well, of course.)
>>  - Made the following code change (to fix the NullReferenceException
>> when NHibernate tries to increment the null value in the database):
>>
>> --- Versioning.cs
>> +++ Versioning.cs       (working copy)
>> @@ -28,6 +28,11 @@
>>            /// <returns>Returns the next value for the version.</returns>
>>            public static object Increment(object version,
>> IVersionType versionType, ISessionImplementor session)
>>            {
>> +            if(version == null)
>> +            {
>> +                version = versionType.Seed(session);
>> +            }
>> +
>>            object next = versionType.Next(version, session);
>>            if (log.IsDebugEnabled)
>>            {
>>
>>   By the way, I also tested to verify that the 3rd change was really
>> necessary. (Since I saw Seed() being used elsewhere, I wasn't sure if
>> it would try again to increment a null value after I fixed my
>> mappings.)
>>
>>   Also, in case anyone else is seeing this problem, the following
>> exception is thrown when I try to specify the type of the version
>> property in the XML as "int?":
>>
>> NHibernate.MappingException : Could not compile the mapping document:
>> Example.hbm.xml
>>  ----> NHibernate.MappingException : Could not determine type for:
>> MyCompany.Model.int?, PROLIN.DAO, for columns:
>> NHibernate.Mapping.Column(VERSION)
>> at NHibernate.Cfg.Configuration.LogAndThrow(Exception exception) in
>> Configuration.cs: line 340
>> at NHibernate.Cfg.Configuration.AddDeserializedMapping(HbmMapping
>> mappingDocument, String documentFileName) in Configuration.cs: line
>> 528
>> at NHibernate.Cfg.Configuration.AddValidatedDocument(NamedXmlDocument
>> doc) in Configuration.cs: line 497
>> at NHibernate.Cfg.Configuration.ProcessMappingsQueue() in
>> Configuration.cs: line 1830
>> at NHibernate.Cfg.Configuration.AddDocumentThroughQueue(NamedXmlDocument
>> document) in Configuration.cs: line 1821
>> at NHibernate.Cfg.Configuration.AddXmlReader(XmlReader hbmReader,
>> String name) in Configuration.cs: line 1814
>> at NHibernate.Cfg.Configuration.AddInputStream(Stream xmlInputStream,
>> String name) in Configuration.cs: line 644
>> at NHibernate.Cfg.Configuration.AddResource(String path, Assembly
>> assembly) in Configuration.cs: line 682
>> at NHibernate.Cfg.Configuration.AddAssembly(Assembly assembly) in
>> Configuration.cs: line 761
>> --MappingException
>> at NHibernate.Mapping.SimpleValue.get_Type() in SimpleValue.cs: line 241
>> at NHibernate.Cfg.XmlHbmBinding.RootClassBinder.BindProperty(HbmVersion
>> versionSchema, Property property, IDictionary`2 inheritedMetas) in
>> RootClassBinder.cs: line 227
>> at NHibernate.Cfg.XmlHbmBinding.RootClassBinder.BindVersion(HbmVersion
>> versionSchema, PersistentClass rootClass, Table table, IDictionary`2
>> inheritedMetas) in RootClassBinder.cs: line 209
>> at NHibernate.Cfg.XmlHbmBinding.RootClassBinder.Bind(HbmClass
>> classSchema, IDictionary`2 inheritedMetas) in RootClassBinder.cs: line
>> 55
>> at NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.AddRootClasses(HbmClass
>> rootClass, IDictionary`2 inheritedMetas) in MappingRootBinder.cs: line
>> 83
>> at
>> NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.AddEntitiesMappings(HbmMapping
>> mappingSchema, IDictionary`2 inheritedMetas) in MappingRootBinder.cs:
>> line 42
>> at NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.Bind(HbmMapping
>> mappingSchema) in MappingRootBinder.cs: line 29
>> at NHibernate.Cfg.Configuration.AddDeserializedMapping(HbmMapping
>> mappingDocument, String documentFileName) in Configuration.cs: line
>> 520
>>
>>   This exception may be an error on my part rather than a bug, since
>> I am not explicitly calling out nullable properties anywhere else in
>> my mapping XML. (I imagine I was trying to do something unsupported,
>> but I don't explicitly state types anywhere else in my mapping XML.)
>> The quirk here is that for a version property (according to the
>> reference manual I found at
>> http://www.nhforge.org/doc/nh/en/index.html, section 5.1.7), the
>> "type" parameter is "(optional - defaults to Int32)". I'm not sure why
>> this wouldn't default to the type defined in the POCO for the version
>> property. Also, the manual states "Version numbers may be of type
>> Int64, Int32, Int16, Ticks, Timestamp, or TimeSpan (or their nullable
>> counterparts in .NET 2.0)", so I assumed I could write "int?".
>>
>> Regards,
>> Mike
>>
>> On Thu, Nov 11, 2010 at 6:12 AM, Fabio Maulo <[email protected]>
>> wrote:
>> > May be you have to know that you can implements your own type for the
>> > version property following the rules of your legacy DB.
>> >
>> > --
>> > Fabio Maulo
>> >
>> >
>> > El 10/11/2010, a las 20:04, Mike Pontillo <[email protected]>
>> escribió:
>> >
>> >> In case anyone was wondering,
>> >>
>> >>   I figured out the problem. I am trying to map a legacy database
>> >> that uses version columns that are nullable. NHibernate threw
>> >> exceptions when I defined the nullable types in my POCOs and the
>> >> NHibernate XML (even though the manual stated that they were supported
>> >> -- so likely a bug) so I defined them as "int". However, I didn't
>> >> notice that some rows (very few - likely mistakes, or cases where
>> >> someone hand-edited the data) in the database indeed have NULL values
>> >> for the version column. If a query ever cached one of these NULL
>> >> values, and NHibernate subsequently performed a dirty check, it will
>> >> throw this exception.
>> >>
>> >>   If I have time, I'll write up a test case and try patching the code
>> >> so NHibernate supports nullable version columns better. I think if
>> >> NHibernate treated NULL version columns as if they had the value 0,
>> >> this would fix the problem.
>> >>
>> >> Regards,
>> >> Mike
>> >>
>> >> On Tue, Nov 9, 2010 at 5:30 PM, Mike Pontillo <[email protected]>
>> wrote:
>> >>> Greetings,
>> >>>
>> >>>   I am using NHibernate 3.0.0 beta 2, and am trying to evolve some
>> >>> prototype code that was using the "session per call" anti-pattern to
>> >>> use a "session per request" approach. I soon noticed that after
>> >>> implementing the session sharing, my unit tests started failing with
>> >>> the following exception:
>> >>>
>> >>> System.NullReferenceException : Object reference not set to an
>> >>> instance of an object.
>> >>> at NHibernate.Type.Int32Type.Next(Object current, ISessionImplementor
>> >>> session) in d:\CSharp\NH\nhibernate\src\NHibernate\Type\Int32Type.cs:
>> >>> line 77
>> >>> at NHibernate.Engine.Versioning.Increment(Object version, IVersionType
>> >>> versionType, ISessionImplementor session) in d:\CSharp\NH\nhibernate
>> >>> \src\NHibernate\Engine\Versioning.cs: line 31
>> >>> at
>> >>>
>> NHibernate.Event.Default.DefaultFlushEntityEventListener.GetNextVersion(FlushEntityEvent
>> >>> event) in d:\CSharp\NH\nhibernate\src\NHibernate\Event\Default
>> >>> \DefaultFlushEntityEventListener.cs: line 331
>> >>> at
>> >>>
>> NHibernate.Event.Default.DefaultFlushEntityEventListener.ScheduleUpdate(FlushEntityEvent
>> >>> event) in d:\CSharp\NH\nhibernate\src\NHibernate\Event\Default
>> >>> \DefaultFlushEntityEventListener.cs: line 242
>> >>> at
>> >>>
>> NHibernate.Event.Default.DefaultFlushEntityEventListener.OnFlushEntity(FlushEntityEvent
>> >>> event) in d:\CSharp\NH\nhibernate\src\NHibernate\Event\Default
>> >>> \DefaultFlushEntityEventListener.cs: line 45
>> >>> at
>> >>>
>> NHibernate.Event.Default.AbstractFlushingEventListener.FlushEntities(FlushEvent
>> >>> event) in d:\CSharp\NH\nhibernate\src\NHibernate\Event\Default
>> >>> \AbstractFlushingEventListener.cs: line 161
>> >>> at
>> >>>
>> NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent
>> >>> event) in d:\CSharp\NH\nhibernate\src\NHibernate\Event\Default
>> >>> \AbstractFlushingEventListener.cs: line 60
>> >>> at
>> >>>
>> NHibernate.Event.Default.DefaultDirtyCheckEventListener.OnDirtyCheck(DirtyCheckEvent
>> >>> event) in d:\CSharp\NH\nhibernate\src\NHibernate\Event\Default
>> >>> \DefaultDirtyCheckEventListener.cs: line 21
>> >>> at NHibernate.Impl.SessionImpl.IsDirty() in
>> d:\CSharp\NH\nhibernate\src
>> >>> \NHibernate\Impl\SessionImpl.cs: line 1510
>> >>>
>> >>>   The failures happened at "random" times, such as when I was about
>> >>> to execute a query and NHibernate would do a dirty check. So I added
>> >>> asserts for session.IsDirty() to try to catch the problem earlier, but
>> >>> I still don't see an obvious cause. The odd thing is, the version
>> >>> property should not be incrementing, since I am only doing read-only
>> >>> work within the session so far. For example, the following code fails:
>> >>>
>> >>>
>> >>> Assert.IsFalse(session.IsDirty());
>> >>>            var query = session.CreateQuery("from " + typeof(T).Name);
>> >>>            var list = query.List<T>();
>> >>>            Console.WriteLine(" HQL query: {0} " + typeof(T).Name + "
>> >>> objects found", list.Count());
>> >>>            Assert.AreEqual(_rowCount, list.Count()); // value cached
>> >>> in test setup
>> >>>            Assert.IsFalse(session.IsDirty());
>> >>>
>> >>>   I have been looking at this all afternoon, and tried to recreate
>> >>> the problem by pasting similar unit test code into the
>> >>> NHibernate.Test.VersionTest unit tests. (No luck yet.) Also, I tried
>> >>> doing a "session.Clear()" before running this code, (which I thought
>> >>> might solve the problem if there was stale data in the session) but it
>> >>> had no effect.
>> >>>
>> >>>   I'm running out of ideas... does anyone have any thoughts on what
>> >>> to look at next?
>> >>>
>> >>> Thanks,
>> >>> Mike
>> >>
>> >> --
>> >> 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]<nhusers%[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]<nhusers%[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]<nhusers%[email protected]>
>> .
>> For more options, visit this group at
>> http://groups.google.com/group/nhusers?hl=en.
>>
>>
>
>
> --
> 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.

Reply via email to