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.  [ 2 posts ] 
Author Message
 Post subject: Deserialization error: SessionFactory?
PostPosted: Wed Oct 28, 2009 9:55 am 
Newbie

Joined: Wed Oct 28, 2009 9:44 am
Posts: 2
I am getting the error "Value cannot be null.\r\nParameter name: key" upon deserializing my remoted object. From the stack trace it looks like it trying to get a reference to session factory. I don't understand that because I use the session factory, session and criteria only temporarily on a server side method of the class. I'm just returning the IList of results to the client, it shouldn't be trying to send over server side objects. Any ideas as to the problem? Thanks

Error:

System.ArgumentNullException occurred
Message="Value cannot be null.\r\nParameter name: key"
Source="mscorlib"
ParamName="key"
StackTrace:
Server stack trace:
at System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value)
at NHibernate.Impl.SessionFactoryObjectFactory.GetNamedInstance(String name)
at NHibernate.Impl.SessionFactoryImpl.GetRealObject(StreamingContext context)
at System.Runtime.Serialization.ObjectManager.ResolveObjectReference(ObjectHolder holder)
at System.Runtime.Serialization.ObjectManager.DoFixups()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Remoting.Channels.CoreChannel.DeserializeBinaryResponseMessage(Stream inputStream, IMethodCallMessage reqMsg, Boolean bStrictBinding)
at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.DeserializeMessage(IMethodCallMessage mcm, ITransportHeaders headers, Stream stream)
at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at TH.Common.Remoting.DataServer.Execute(ExecutableBase executableObject)
at TH.Common.Business.ExecutableBase.Execute() in C:\Source\TH.Common\Falanouc\Business\ExecutableBase.cs:line 19
InnerException:

NHibernate Base class:

Code:
[Serializable]
    public abstract class NHibernateExecutableBase : NonDataExecutableBase
    {
        public override ExecutableBase ServerExecute()
        {
            //var sessionFactory = SessionManager.Instance.SessionFactory;
           
            using (var sessionFactory = SessionFactory.CreateSessionFactory())
            {
                using (var session = sessionFactory.OpenSession())
                {
                    var transaction = session.BeginTransaction();

                    try
                    {
                        ServerExecute(session);
                    }
                    catch (Exception)
                    {
                        transaction.Rollback();
                        throw;
                    }

                    transaction.Commit();
                }
            }

            return this;
        }

        public virtual void ServerExecute(
            ISession session)
        {
            throw new NotImplementedException("Must be overriden in derived class");
        }
    }


Criteria Class:

Code:
[Serializable]
    public class NHibernateCriteriaExecutable<TPoco> : NHibernateExecutableBase
    {
        public DetachedCriteria Criteria { get; set; }

        public IList<TPoco> Results { get; private set; }

        public override void ServerExecute(ISession session)
        {
            var serverSideCriteria = Criteria.GetExecutableCriteria(session);
            this.Results = serverSideCriteria.List<TPoco>();
        }

        public static IList<TPoco> Process(DetachedCriteria criteria)
        {
            var eo = new NHibernateCriteriaExecutable<TPoco> {Criteria  = criteria};
            eo = (NHibernateCriteriaExecutable<TPoco>) eo.Execute();
            return eo.Results;
        }
    }


Partial calling code:

Code:
var query = DetachedCriteria.For<ProviderTrainingSearchResult>();

            if (null != phyID)
                query.Add(Expression.Eq("PHY_ID", phyID.Value));

            var results = NHibernateCriteriaExecutable<ProviderTrainingSearchResult>.Process(
                query);
            Debug.WriteLine(results.Count);


Top
 Profile  
 
 Post subject: Re: Deserialization error: SessionFactory?
PostPosted: Wed Oct 28, 2009 4:58 pm 
Newbie

Joined: Wed Oct 28, 2009 9:44 am
Posts: 2
Took some digging but after a day of pulling my hair out I figured out the problem. This post lead me to the culprit.

DetachedCriteria.GetExecutableCriteria(session) appears to modify the original detached criteria and apparently attaches the session to it (not really detached then so much I think). I'm left with either trying to clone criteria or for now just setting the detached criteria passed over from the client to null before making the trip back across the wire.

This behavior is certainly not obvious/expected/desirable. Adjusted working code is below.

Code:
[Serializable]
    public class NHibernateCriteriaExecutable<TPoco> : NHibernateExecutableBase
    {
        public NHibernateCriteriaExecutable(DetachedCriteria criteria)
        {
            this.Criteria = criteria;
        }

        public DetachedCriteria Criteria { get; set; }
       
        public IList<TPoco> Results { get; private set; }

        protected override void ServerExecute(ISession session)
        {
            // GetExecutableCriteria() is the devil! Appears to modify the original
            // criteria, attaching session to it so we end up with a deserialization
            // error going back to client with SessionFactory
            // see https://forum.hibernate.org/viewtopic.php?f=25&t=1000604&sid=047e628773cd58f058e4949cff160201
            // fix is after setting Results below
            var serverSideCriteria = Criteria.GetExecutableCriteria(session);

            this.Results = serverSideCriteria.List<TPoco>();

            // set original criteria to null so it doesn't have any attached server side
            // session objects. ideally we might clone it but right now I don't care if
            // the criteria is lost afterwards, it's only needed on server side for query
            Criteria = null;
        }

        public static IList<TPoco> Process(DetachedCriteria criteria)
        {
            var eo = new NHibernateCriteriaExecutable<TPoco>(criteria);
            eo = (NHibernateCriteriaExecutable<TPoco>) eo.Execute();
            return eo.Results;
        }
    }


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 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.