-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: NHibernate and .Net Framework 4.0 Issue
PostPosted: Thu Apr 14, 2011 7:24 am 
Newbie

Joined: Thu Apr 14, 2011 4:54 am
Posts: 3
Dear all

First of all I'd like to state that I'm new to NHibernate, and may require some pointers in order to get you all the info you need.

I have been struggling with an issue for several days now, and I feel I've hit a brick wall. I have searched google, as well as the FAQs and this forum, but no luck so far. Any help would be much appreciated.

I have recently converted an Nhibernate application from .Net Framework 3.5SP1 to 4.0. This application uses NHibernate 3.2 and Prism 4.

The application was running fine until I upgraded to .Net 4.0.

The issue I am now having is that on startup, when Prism (bootstrapper) tries to initialise my Data Access module it throws an error as follows. The code compiles without a hitch:

Code:
System.TypeLoadException: Method 'NullSafeGet' in type 'BCS.QMIS.DataAccess.Hibernate.UserBlob' from assembly 'QMISDataAccess, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
   at System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes)
   at System.Reflection.RuntimeAssembly.GetExportedTypes()
   at Microsoft.Practices.Prism.Modularity.DirectoryModuleCatalog.InnerModuleInfoLoader.<>c__DisplayClassf.<GetNotAllreadyLoadedModuleInfos>b__b(FileInfo file)
   at System.Linq.Enumerable.<SelectManyIterator>d__14`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Microsoft.Practices.Prism.Modularity.DirectoryModuleCatalog.InnerModuleInfoLoader.GetModuleInfos(String path)
   at Microsoft.Practices.Prism.Modularity.DirectoryModuleCatalog.InnerModuleInfoLoader.GetModuleInfos(String path)
   at Microsoft.Practices.Prism.Modularity.DirectoryModuleCatalog.InnerLoad()
   at Microsoft.Practices.Prism.Modularity.ModuleCatalog.Load()
   at Microsoft.Practices.Prism.Modularity.ModuleCatalog.Initialize()
   at Microsoft.Practices.Prism.Modularity.ModuleManager.Run()
   at Microsoft.Practices.Prism.UnityExtensions.UnityBootstrapper.InitializeModules()
   at BCS.Common.CAL.MainApp.BootStrapper.InitializeModules() in D:\Develop\BCS\Common\CAL\Main App\MainApp\BootStrapper.cs:line 44
   at Microsoft.Practices.Prism.UnityExtensions.UnityBootstrapper.Run(Boolean runWithDefaultConfiguration)
   at Microsoft.Practices.Prism.Bootstrapper.Run()
   at BCS.Common.CAL.MainApp.App.<.ctor>b__0() in D:\Develop\BCS\Common\CAL\Main App\MainApp\App.xaml.cs:line 53


This error suggests that I haven't implemented the NullSafeGet method for my CustomType: UserBlob. However, I have clearly implemented it. Please see the following code for UserBlob.

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

using NHibernate;
using NHibernate.SqlTypes;
using NHibernate.Util;
using NHibernate.UserTypes;

namespace BCS.QMIS.DataAccess.Hibernate
{
    public class UserBlob : IUserType
    {
        public UserBlob()
        {
        }

        private BinarySqlType sqlType = new BinarySqlType(2147483647);

        #region IUserType Members

        public object Assemble(object cached, object owner)
        {
            if (cached == null)
            {
                return null;
            }
            else
            {
                return DeepCopy(cached);
            }
        }

        public object DeepCopy(object value)
        {
            return (value == null) ? null : DeepCopyNotNull(value);
        }

        private object DeepCopyNotNull(Object value)
        {
            byte[] bytes = (byte[])value;
            byte[] result = new byte[bytes.Length];
            Array.Copy(bytes, 0, result, 0, bytes.Length);
            return result;
        }

        public object Disassemble(object value)
        {
            if (value == null)
            {
                return null;
            }
            else
            {
                return DeepCopy(value);
            }
        }

        public int GetHashCode(object x)
        {
            unchecked
            {
                byte[] bytes = (byte[])x;
                int hashCode = 1;
                for (int j = 0; j < bytes.Length; j++)
                {
                    hashCode = 31 * hashCode + bytes[j];
                }
                return hashCode;
            }
        }

        public bool IsMutable
        {
            get { return true; }
        }

        public object NullSafeGet(System.Data.IDataReader rs, string[] names, object owner)
        {
            int index = rs.GetOrdinal(names[0]);
            int length = (int)rs.GetBytes(index, 0, null, 0, 0);
            byte[] buffer = new byte[length];

            int offset = 0;

            while (length - offset > 0)
            {
                int countRead = (int)rs.GetBytes(index, offset, buffer, offset, length - offset);
                offset += countRead;

                if (countRead == 0)
                {
                    // Should never happen
                    throw new AssertionFailure("Error in UserBlob.Get, IDataRecord.GetBytes read zero bytes");
                }
            }

            return buffer;
        }

        public void NullSafeSet(System.Data.IDbCommand cmd, object value, int index)
        {
            ((IDataParameter)cmd.Parameters[index]).Value = (byte[])value;
        }

        public object Replace(object original, object target, object owner)
        {
            return DeepCopy(original);
        }

        public Type ReturnedType
        {
            get { return typeof(byte[]); }
        }

        public NHibernate.SqlTypes.SqlType[] SqlTypes
        {
            get { return new SqlType[] { sqlType }; }
        }

        public new bool Equals(object x, object y)
        {
            if (x == y)
            {
                return true;
            }
            if (x == null || y == null)
            {
                return false;
            }

            return CollectionHelper.CollectionEquals<byte>((byte[])x, (byte[])y);
        }

        #endregion
    }
}


The nearest I have come to an explanation of this issue is from the following link:

http://stackoverflow.com/questions/948785/typeloadexception-says-no-implementation-but-it-is-implemented

My gut tells me I am bumping into an issue with using different versions of the NHibernate dll, but I have stripped my system of all copies of this dll, and I'm sure my application is only using the one I want.

Do I need to recompile NHibernate using .Net 4.0? If so, how is this possible? The version of Nant that is able to compile against .Net 4.0 is still in its Alpha stages and it throws an error when I try to compile NHibernate using .Net 4.0.

Has anyone seen similar behaviour or can suggest some pointers as to how I can debug this, I would very much appreciate the help.

I'm trying to provide as much info as I can without writing an essay, so if there is anything else you need, please let me know.

Thanks very much for reading.
Ken


Top
 Profile  
 
 Post subject: Re: NHibernate and .Net Framework 4.0 Issue
PostPosted: Thu Apr 14, 2011 7:41 am 
Newbie

Joined: Thu Apr 14, 2011 4:54 am
Posts: 3
I'd like to add that I have experienced the same issue with NHibernate 2, so I don't think the issue is specific to 3.2.

Further update:

I have found that the problem is specific to IUserType. Here is why.

1.) By changing my implementation of IUserType to not implement this interface, I get round the immediate issue.
2.) By removing a reference to NHibernate entirely, the code no longer compiles because there are several other lines of code that are dependent on NHibernate (e.g. private BinarySqlType sqlType = new BinarySqlType(2147483647);)

The fact that the error goes away when I take the IUserType out of the picture, as well as the fact that my implementation is perfectly happy about other dependencies on NHibernate, suggests that it is the IUserType, which is the problem.


Top
 Profile  
 
 Post subject: Re: NHibernate and .Net Framework 4.0 Issue
PostPosted: Fri Apr 15, 2011 7:26 am 
Newbie

Joined: Thu Apr 14, 2011 4:54 am
Posts: 3
Found a work around.

I've split all Prism related functionality from the project in question and put it in a separate project.

Issue closed.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.