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.  [ 10 posts ] 
Author Message
 Post subject: Failed to compare two elements in the array
PostPosted: Fri Aug 25, 2006 4:56 am 
Senior
Senior

Joined: Sat Sep 03, 2005 12:54 am
Posts: 139
Hi,

I am getting the above error when I specify the sort attribute on a set in one of my entities. It seems to be related to the rehydration of the entity from the cache because the sort seems to be working on the initial load of the collection.

The stack trace for the exception is as follows:

Code:
Failed to compare two elements in the array.

at System.Array.BinarySearch(Array array, Int32 index, Int32 length, Object value, IComparer comparer) at System.Collections.SortedList.IndexOfKey(Object key) at System.Collections.SortedList.get_Item(Object key) at Iesi.Collections.DictionarySet.Add(Object o) at NHibernate.Collection.Set.InitializeFromCache(ICollectionPersister persister, Object disassembled, Object owner) at NHibernate.Impl.SessionImpl.InitializeCollectionFromCache(Object id, Object owner, ICollectionPersister persister, PersistentCollection collection) at NHibernate.Impl.SessionImpl.InitializeCollection(PersistentCollection collection, Boolean writing) at NHibernate.Collection.PersistentCollection.ForceInitialization() at NHibernate.Impl.SessionImpl.InitializeNonLazyCollections() at NHibernate.Impl.SessionImpl.AssembleCacheEntry(CacheEntry entry, Object id, IClassPersister persister, Object optionalObject) at NHibernate.Impl.SessionImpl.DoLoad(Type theClass, Object id, Object optionalObject, LockMode lockMode, Boolean checkDeleted) at NHibernate.Impl.SessionImpl.DoLoadByClass(Type clazz, Object id, Boolean checkDeleted, Boolean allowProxyCreation) at NHibernate.Impl.SessionImpl.InternalLoad(Type clazz, Object id) at NHibernate.Type.ManyToOneType.ResolveIdentifier(Object id, ISessionImplementor session) at NHibernate.Type.ManyToOneType.Assemble(Object oid, ISessionImplementor session, Object owner) at NHibernate.Impl.CacheEntry.Assemble(Object[] values, Object result, Object id, IClassPersister persister, IInterceptor interceptor, ISessionImplementor session) at NHibernate.Impl.CacheEntry.Assemble(Object instance, Object id, IClassPersister persister, IInterceptor interceptor, ISessionImplementor session) at NHibernate.Impl.SessionImpl.AssembleCacheEntry(CacheEntry entry, Object id, IClassPersister persister, Object optionalObject) at NHibernate.Impl.SessionImpl.DoLoad(Type theClass, Object id, Object optionalObject, LockMode lockMode, Boolean checkDeleted) at NHibernate.Impl.SessionImpl.DoLoadByClass(Type clazz, Object id, Boolean checkDeleted, Boolean allowProxyCreation) at NHibernate.Impl.SessionImpl.InternalLoad(Type clazz, Object id) at NHibernate.Type.ManyToOneType.ResolveIdentifier(Object id, ISessionImplementor session) at NHibernate.Type.ManyToOneType.Assemble(Object oid, ISessionImplementor session, Object owner) at NHibernate.Impl.CacheEntry.Assemble(Object[] values, Object result, Object id, IClassPersister persister, IInterceptor interceptor, ISessionImplementor session) at NHibernate.Impl.CacheEntry.Assemble(Object instance, Object id, IClassPersister persister, IInterceptor interceptor, ISessionImplementor session) at NHibernate.Impl.SessionImpl.AssembleCacheEntry(CacheEntry entry, Object id, IClassPersister persister, Object optionalObject) at NHibernate.Impl.SessionImpl.DoLoad(Type theClass, Object id, Object optionalObject, LockMode lockMode, Boolean checkDeleted) at NHibernate.Impl.SessionImpl.DoLoadByClass(Type clazz, Object id, Boolean checkDeleted, Boolean allowProxyCreation) at NHibernate.Impl.SessionImpl.InternalLoad(Type clazz, Object id) at NHibernate.Type.ManyToOneType.ResolveIdentifier(Object id, ISessionImplementor session) at NHibernate.Type.ManyToOneType.Assemble(Object oid, ISessionImplementor session, Object owner) at NHibernate.Impl.CacheEntry.Assemble(Object[] values, Object result, Object id, IClassPersister persister, IInterceptor interceptor, ISessionImplementor session) at NHibernate.Impl.CacheEntry.Assemble(Object instance, Object id, IClassPersister persister, IInterceptor interceptor, ISessionImplementor session) at NHibernate.Impl.SessionImpl.AssembleCacheEntry(CacheEntry entry, Object id, IClassPersister persister, Object optionalObject) at NHibernate.Impl.SessionImpl.DoLoad(Type theClass, Object id, Object optionalObject, LockMode lockMode, Boolean checkDeleted) at NHibernate.Impl.SessionImpl.DoLoadByClass(Type clazz, Object id, Boolean checkDeleted, Boolean allowProxyCreation) at NHibernate.Impl.SessionImpl.InternalLoad(Type clazz, Object id) at NHibernate.Type.ManyToOneType.ResolveIdentifier(Object id, ISessionImplementor session) at NHibernate.Type.ManyToOneType.Assemble(Object oid, ISessionImplementor session, Object owner) at NHibernate.Impl.CacheEntry.Assemble(Object[] values, Object result, Object id, IClassPersister persister, IInterceptor interceptor, ISessionImplementor session) at NHibernate.Impl.CacheEntry.Assemble(Object instance, Object id, IClassPersister persister, IInterceptor interceptor, ISessionImplementor session) at NHibernate.Impl.SessionImpl.AssembleCacheEntry(CacheEntry entry, Object id, IClassPersister persister, Object optionalObject) at NHibernate.Impl.SessionImpl.DoLoad(Type theClass, Object id, Object optionalObject, LockMode lockMode, Boolean checkDeleted) at NHibernate.Impl.SessionImpl.DoLoadByClass(Type clazz, Object id, Boolean checkDeleted, Boolean allowProxyCreation) at NHibernate.Impl.SessionImpl.Get(Type clazz, Object id) at NHibernate.Helper.Database.Get(Type type, Object id)

Object reference not set to an instance of an object.

at MyDomain.Entity.EntityComparer.Compare(Object x, Object y) at System.Array.BinarySearch(Array array, Int32 index, Int32 length, Object value, IComparer comparer)


When I debug this, the 2 objects that are being compared in my IComparer seem to be in a strange state, i.e. the private variables contain valid values but trying to access the public properties generates an ArgumentNullException in the debugger.

I have enabled caching on the parent, the child and the collection on the parent and when I disable the caching on the child, I no longer seem to get this error.

I am wondering if this is a bug in there somewhere or if it is something that I am doing incorrectly?

Thanks,

Jason


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 27, 2006 4:59 pm 
Senior
Senior

Joined: Wed Jun 15, 2005 4:17 am
Posts: 156
how your Compare method looks like? are your objects lazy loaded? post more details.

radu


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 27, 2006 5:47 pm 
Senior
Senior

Joined: Sat Sep 03, 2005 12:54 am
Posts: 139
Hi Radu,

My Compare method looks like this:

Code:
        public int Compare(object x, object y)
        {

            if (x is Child == false || y is Child == false)
            {
                throw new ApplicationException(Resources.ChildComparer_ObjectTypesInvalid);
            }

            return ((Child)x).RelatedObject.Name.CompareTo(((Child)y).RelatedObject.Name);

        }


and the public propery for RelatedObject looks like this:

Code:
        public virtual RelatedObject RelatedObject
        {
            get
            {
                return this._relatedObject;
            }
            set
            {
                this._relatedObject = value;
            }
        }


When debugged, the private variable _relatedObject contains a valid object in both objects being compared, but the public property doesn't seem to be accessible for some reason in the debugger (I see an exception for every public property in the watch window).

The mapping file for the parent looks like this:

Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" schema="dbo">
  <class name="MyDomain.Parent, MyDomain" table="Parent">

    <cache usage="read-write"/>

    <id name="ID" type="Int32" column="ID">
      <generator class="identity"/>
    </id>

    ...

    <set name="Children" table="Child" inverse="true" lazy="false" cascade="all-delete-orphan" sort="MyDomain.ChildComparer, MyDomain">
      <cache usage="read-write"/>
      <key column="ParentID"/>
      <one-to-many class="MyDomain.Child, MyDomain"/>
    </set>

  </class>
</hibernate-mapping>


and the mapping file for the Child looks like this:

Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" schema="dbo">
  <class name="MyDomain.Child, MyDomain" table="Child">

    <cache usage="read-write"/>

    <id name="ID" type="Int32" column="ID">
      <generator class="identity"/>
    </id>

    ...
   
    <many-to-one name="Parent" column="ParentID" class="MyDomain.Parent, MyDomain" not-null="true"/>

    <many-to-one name="RelatedObject" column="RelatedObjectID" class="RelatedObject, MyDomain" not-null="true"/>

  </class>
</hibernate-mapping>


and the mapping file for the related object looks like this:

Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" schema="dbo">
   <class name="MyDomain.RelatedObject, MyDomain" table="RelatedObject">

    <cache usage="read-write" />

    <id name="ID" type="Int32" column="ID">
         <generator class="identity"/>
      </id>

    <property name="Name" column="Name" type="String" length="200" not-null="true"/>
    ...
   
  </class>
</hibernate-mapping>



As mentioned, the comparison does work when the objects are initially loaded from the DB because I can look at a drop down list that has been sorted correctly. However, when a postback occurs and the objects get re-hydrated from the 2nd level cache, something seems to go wrong with the sorting.

Let me know if I can provide any further information.

Thanks,

Jason


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 28, 2006 5:36 pm 
Senior
Senior

Joined: Wed Jun 15, 2005 4:17 am
Posts: 156
It seems that you've got a null reference somewhere in your Compare method. I sugest to add more checking code in the compare to see what reference is null. I suspect that your RelatedObject property returns null. Just to check what happens remove the virtual from the property definition. By the way, you didn't mention what version of NHibernate are you using.

radu


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 30, 2006 1:41 am 
Senior
Senior

Joined: Sat Sep 03, 2005 12:54 am
Posts: 139
After some more extensive debugging, I have managed to get a bit closer to the problem and have been able to create a small test case application that can reliably reproduce the problem. It looks like it might be a bug at this stage as I can't see anything that is wrong with the code in the mini-app.

All of the objects are sorted OK when they are first loaded from the DB but it goes awry after a postback triggers the rehydration of the objects from the 2nd level cache.

It looks like it takes a certain combination of relationships to cause the problem:

Parent object has 2 child collections (A & B)
Object in collection A references an object in collection B
Object in collection A loaded from the session after it has already been added to the 2nd level cache

If I load the parent from the session, then all the collections are loaded OK and the sorting works fine. If I load an object contained in collection A from the session, then the error occurs with the sorting.

Here is all the code from the mini-app that reproduces the problem (I have put stuff into single files wherever possible to make it easier to paste in here!). There is a domain assembly called MyDomain and a website called MyDomainUI that references MyDomain.

MyDomain - DomainObjects.cs:

Code:
using System;
using System.Collections;
using System.Text;
using Iesi.Collections;

namespace MyDomain
{

    public class Parent
    {

        private int _id;
        private string _name;
        private ISet _children;
        private ISet _differentChildren;

        public virtual int ID
        {
            get
            {
                return this._id;
            }
            set
            {
                this._id = value;
            }
        }

        public virtual string Name
        {
            get
            {
                return this._name;
            }
            set
            {
                this._name = value;
            }
        }

        public virtual ISet Children
        {
            get
            {
                return this._children;
            }
            set
            {
                this._children = value;
            }
        }

        public virtual ISet DifferentChildren
        {
            get
            {
                return this._differentChildren;
            }
            set
            {
                this._differentChildren = value;
            }
        }

        public Parent()
        {
            this._children = new HashedSet();
            this._differentChildren = new HashedSet();
        }

    }

    public class Child
    {

        private int _id;
        private string _name;
        private Parent _parent;
        private RelatedObject _relatedObject;

        public virtual int ID
        {
            get
            {
                return this._id;
            }
            set
            {
                this._id = value;
            }
        }

        public virtual string Name
        {
            get
            {
                return this._name;
            }
            set
            {
                this._name = value;
            }
        }

        public virtual Parent Parent
        {
            get
            {
                return this._parent;
            }
            set
            {
                this._parent = value;
            }
        }

        public virtual RelatedObject RelatedObject
        {
            get
            {
                return this._relatedObject;
            }
            set
            {
                this._relatedObject = value;
            }
        }

    }

    public class DifferentChild
    {

        private int _id;
        private string _name;
        private Parent _parent;
        private Child _child;

        public virtual int ID
        {
            get
            {
                return this._id;
            }
            set
            {
                this._id = value;
            }
        }

        public virtual string Name
        {
            get
            {
                return this._name;
            }
            set
            {
                this._name = value;
            }
        }

        public virtual Parent Parent
        {
            get
            {
                return this._parent;
            }
            set
            {
                this._parent = value;
            }
        }

        public virtual Child Child
        {
            get
            {
                return this._child;
            }
            set
            {
                this._child = value;
            }
        }

    }

    public class RelatedObject
    {

        private int _id;
        private string _name;

        public virtual int ID
        {
            get
            {
                return this._id;
            }
            set
            {
                this._id = value;
            }
        }

        public virtual string Name
        {
            get
            {
                return this._name;
            }
            set
            {
                this._name = value;
            }
        }

    }

    public class ChildComparer : IComparer
    {

        public int Compare(object x, object y)
        {
            return ((Child)x).RelatedObject.Name.CompareTo(((Child)y).RelatedObject.Name);
        }

    }

}


MyDomain - DomainObjects.hbm.xml:

Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" schema="dbo">
  <class name="MyDomain.Parent, MyDomain" table="Parent">

    <cache usage="read-write"/>

    <id name="ID" type="Int32" column="ID">
      <generator class="identity"/>
    </id>

    <property name="Name" column="Name" type="String" length="200" not-null="true"/>

    <set name="Children" table="Child" inverse="true" lazy="false" cascade="all-delete-orphan" sort="MyDomain.ChildComparer, MyDomain">
      <cache usage="read-write"/>
      <key column="ParentID"/>
      <one-to-many class="MyDomain.Child, MyDomain"/>
    </set>

    <set name="DifferentChildren" table="DifferentChild" inverse="true" lazy="false" cascade="all-delete-orphan">
      <cache usage="read-write"/>
      <key column="ParentID"/>
      <one-to-many class="MyDomain.DifferentChild, MyDomain"/>
    </set>

  </class>
  <class name="MyDomain.Child, MyDomain" table="Child">

    <cache usage="read-write"/>

    <id name="ID" type="Int32" column="ID">
      <generator class="identity"/>
    </id>

    <property name="Name" column="Name" type="String" length="200" not-null="true"/>

    <many-to-one name="Parent" column="ParentID" class="MyDomain.Parent, MyDomain" not-null="true"/>
    <many-to-one name="RelatedObject" column="RelatedObjectID" class="MyDomain.RelatedObject, MyDomain" not-null="true"/>

  </class>
  <class name="MyDomain.DifferentChild, MyDomain" table="DifferentChild">

    <cache usage="read-write"/>

    <id name="ID" type="Int32" column="ID">
      <generator class="identity"/>
    </id>

    <property name="Name" column="Name" type="String" length="200" not-null="true"/>

    <many-to-one name="Parent" column="ParentID" class="MyDomain.Parent, MyDomain" not-null="true"/>
    <many-to-one name="Child" column="ChildID" class="MyDomain.Child, MyDomain" />

  </class>
  <class name="MyDomain.RelatedObject, MyDomain" table="RelatedObject">

    <cache usage="read-write"/>

    <id name="ID" type="Int32" column="ID">
      <generator class="identity"/>
    </id>

    <property name="Name" column="Name" type="String" length="200" not-null="true"/>

  </class>
</hibernate-mapping>


MyDomainUI - Global.asax:

Code:
<%@ Application Language="C#" %>

<script runat="server">

    void Application_Start(object sender, EventArgs e)
    {
        NHibernate.Cfg.Configuration configuration = new NHibernate.Cfg.Configuration();
        configuration.AddAssembly("MyDomain");
        Application["SessionFactory"] = configuration.BuildSessionFactory();
    }
   
    void Application_End(object sender, EventArgs e)
    {
        //  Code that runs on application shutdown

    }
       
    void Application_Error(object sender, EventArgs e)
    {
        // Code that runs when an unhandled error occurs

    }

    void Session_Start(object sender, EventArgs e)
    {
        // Code that runs when a new session is started

    }

    void Session_End(object sender, EventArgs e)
    {
        // Code that runs when a session ends.
        // Note: The Session_End event is raised only when the sessionstate mode
        // is set to InProc in the Web.config file. If session mode is set to StateServer
        // or SQLServer, the event is not raised.

    }
       
</script>


MyDomainUI - Default.aspx:

Code:
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
        Parent name: <asp:Label ID="_parentNameLabel" runat="server"></asp:Label>
        <asp:GridView ID="_childGrid" runat="server" OnRowEditing="_childGrid_RowEditing" DataKeyNames="ID">
            <Columns>
                <asp:CommandField ShowEditButton="true" />
            </Columns>
        </asp:GridView>
    </form>
</body>
</html>


MyDomainUI - Default.aspx.cs:

Code:
using System;
using System.Collections;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using NHibernate;
using MyDomain;

public partial class _Default : System.Web.UI.Page
{
   
    protected void Page_Load(object sender, EventArgs e)
    {

        if (this.IsPostBack == false)
        {
            this.Initialise();
        }

    }

    private void Initialise()
    {
        ISession session = this.OpenSession();
        Parent parent;
        parent = (Parent)session.Get(typeof(Parent), 1);
        this._parentNameLabel.Text = parent.Name;
        this._childGrid.DataSource = parent.DifferentChildren;
        this._childGrid.DataBind();
        session.Close();
    }

    protected void _childGrid_RowEditing(object sender, GridViewEditEventArgs e)
    {
        ISession session = this.OpenSession();
        int id = (int)this._childGrid.DataKeys[e.NewEditIndex].Value;
        DifferentChild differentChild = (DifferentChild)session.Get(typeof(DifferentChild), id);
        session.Close();
    }

    private ISession OpenSession()
    {
        ISessionFactory factory = (ISessionFactory)Application["SessionFactory"];
        return factory.OpenSession();
    }

}


MyDomainUI - Web.config:

Code:
<?xml version="1.0"?>
<!--
    Note: As an alternative to hand editing this file you can use the
    web admin tool to configure settings for your application. Use
    the Website->Asp.Net Configuration option in Visual Studio.
    A full list of settings and comments can be found in
    machine.config.comments usually located in
    \Windows\Microsoft.Net\Framework\v2.x\Config
-->
<configuration>
   <configSections>
      <section name="syscache" type="NHibernate.Caches.SysCache.SysCacheSectionHandler,NHibernate.Caches.SysCache"/>
      <section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
   </configSections>
   <nhibernate>
      <add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"></add>
      <add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver"></add>
      <add key="hibernate.connection.connection_string" value="Initial Catalog=MyDomain;Data Source=(local);User ID=sa;password=verbatim;"></add>
      <add key="hibernate.connection.isolation" value="ReadCommitted"></add>
      <add key="hibernate.default_schema" value="MyDomain.dbo"></add>
      <add key="hibernate.show_sql" value="false"></add>
      <add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect"></add>
      <add key="hibernate.query.substitutions" value="true 1, false 0, yes 'Y', no 'N'"></add>
      <add key="hibernate.hibernate.cache.provider_class" value="NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache"></add>
      <add key="hibernate.expiration" value="600"></add>
      <add key="hibernate.cache.use_query_cache" value="true"></add>
   </nhibernate>
   <appSettings/>
   <connectionStrings/>
   <system.web>
      <!--
            Set compilation debug="true" to insert debugging
            symbols into the compiled page. Because this
            affects performance, set this value to true only
            during development.
        -->
      <compilation debug="true"/>
      <!--
            The <authentication> section enables configuration
            of the security authentication mode used by
            ASP.NET to identify an incoming user.
        -->
      <authentication mode="Windows"/>
      <!--
            The <customErrors> section enables configuration
            of what to do if/when an unhandled error occurs
            during the execution of a request. Specifically,
            it enables developers to configure html error pages
            to be displayed in place of a error stack trace.

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" redirect="NoAccess.htm" />
            <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
        -->
   </system.web>
</configuration>


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 01, 2006 7:16 am 
Senior
Senior

Joined: Sat Sep 03, 2005 12:54 am
Posts: 139
Is anyone able to see if there is something I am doing wrong here or whether this is possibly a bug?

At this stage, it appears to be a bug to me and I was planning on creating a JIRA for it along with the small test app that I put together to reproduce the problem.

Thanks,

Jason


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 01, 2006 7:27 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
jason.hill wrote:
Is anyone able to see if there is something I am doing wrong here or whether this is possibly a bug?

At this stage, it appears to be a bug to me and I was planning on creating a JIRA for it along with the small test app that I put together to reproduce the problem.

Thanks,

Jason


Your compare method does not allow one (or both) child to be a null.

Also, compare would fail if any of x.RelatedObject, x.RelatedObject.Name or y.RelatedObject is equal to null.

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 01, 2006 4:46 pm 
Senior
Senior

Joined: Sat Sep 03, 2005 12:54 am
Posts: 139
Hi Gert,

The RelatedObject and RelatedObject.Name properties are non-nullable (enforced at the DB level) and the objects that are being loaded and compared have values in those properties.

However, when the obejcts are rehydrated from the cache, one of the objects has null in all of the properties apart from the ID for some reason (which I think is the bug). You will see this happen if you run the sample that I provided.

Here is the DDL to create and populate the DB:

Code:
create table dbo.DifferentChild (
  ID INT IDENTITY NOT NULL,
   Name NVARCHAR(200) not null,
   ParentID INT not null,
   ChildID INT null,
   primary key (ID)
)
create table dbo.Parent (
  ID INT IDENTITY NOT NULL,
   Name NVARCHAR(200) not null,
   primary key (ID)
)
create table dbo.Child (
  ID INT IDENTITY NOT NULL,
   Name NVARCHAR(200) not null,
   ParentID INT not null,
   RelatedObjectID INT not null,
   primary key (ID)
)
create table dbo.RelatedObject (
  ID INT IDENTITY NOT NULL,
   Name NVARCHAR(200) not null,
   primary key (ID)
)
alter table dbo.DifferentChild  add constraint FK99A478B99172C8FE foreign key (ChildID) references dbo.Child
alter table dbo.DifferentChild  add constraint FK99A478B99B59280D foreign key (ParentID) references dbo.Parent
alter table dbo.Child  add constraint FK19AC06849B59280D foreign key (ParentID) references dbo.Parent
alter table dbo.Child  add constraint FK19AC06846E869175 foreign key (RelatedObjectID) references dbo.RelatedObject

insert into Parent (Name) values('Parent')
insert into RelatedObject (Name) values ('Related Object 1')
insert into RelatedObject (Name) values ('Related Object 2')
insert into Child (ParentID, RelatedObjectID, Name) values(1, 1, 'Child 1.1')
insert into Child (ParentID, RelatedObjectID, Name) values(1, 2, 'Child 1.2')
insert into Child (ParentID, RelatedObjectID, Name) values(1, 1, 'Child 1.1')
insert into DifferentChild (ParentID, ChildID, Name) values(1, 1, 'Different Child 1.1')
insert into DifferentChild (ParentID, ChildID, Name) values(1, 2, 'Different Child 1.2')


Cheers,

Jason


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 02, 2006 1:09 pm 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
jason.hill wrote:
However, when the obejcts are rehydrated from the cache, one of the objects has null in all of the properties apart from the ID for some reason (which I think is the bug). You will see this happen if you run the sample that I provided.


There might be some valid reasons why the object is empty - like, if it is not yet lazy-loaded, or if the object has been modified and needs to be reloaded. But I do not understand, why is the collection sorted before fixing those issues... Maybe You should dig a little bit further, and make a bug report?

Gret

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 05, 2006 3:00 am 
Senior
Senior

Joined: Sat Sep 03, 2005 12:54 am
Posts: 139
After stepping through the NH code in the debugger, it appears that the object is in a "Loading" state when it is added to an internal set, which in turn triggers the sort. I guess that because the object is in a loading state, all of the properties have not been fully rehydrated from the cache yet and therefore the sort fails because an expected non-null value is in fact null.

I really don't know enough about the internal workings of NH to be able to get too much further on this so I think I will add a JIRA and see what the NH team think.

Cheers,

Jason


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