-->
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.  [ 6 posts ] 
Author Message
 Post subject: CreateFilter and "The collection was unreferenced"
PostPosted: Thu Feb 09, 2006 4:06 pm 
Newbie

Joined: Thu Feb 09, 2006 3:44 pm
Posts: 5
Hi

For navigating my associations with NHibernate 1.0.2, I thought I'd start of easy with a simple test of the CreateFilter operation. But before I knew it I ran into a "the collection was unreferenced" exception and I don't know what I'm doing wrong!

Could you please help?! The code is below and the problem occurs in the Country.GetName() operation.

Thanks,

Pascal

Country.cs:

Code:
using System;
using System.Collections;
using Iesi.Collections;
using NHibernate;
using NHibernate.Expression;
using System.Collections.Generic;
using System.Text;

namespace Hcp.Domain.CountryModule
{
    public class Country : IEntity
    {
        private int id;
        private string code;
        private ISet countryNames;

        public int Id
        {
            get { return id; }
            set { id = value; }
        }

        public string Code
        {
            get { return code; }
            set { code = value; }
        }

        public ISet CountryNames
        {
            get { return this.countryNames; }
            set { this.countryNames = value; }
        }

        public string GetName(string languageCode)
        {
            using (Repository repository = new Repository())
            {
                repository.Open();
                IQuery q = repository.Session.CreateFilter(CountryNames, "where this.Id = 6");
               
                if (q.List().Count > 0){
                    return ((CountryName)q.List()[0]).Name;
                }
                else
                {
                    return "Unknown";
                }
            }
        }
    }
}


CountryName.cs
Code:
using System;
using System.Collections.Generic;
using System.Text;

namespace Hcp.Domain.CountryModule
{
    public class CountryName: IEntity
    {
        private int id;
        private string name;

        public int Id
        {
            get { return id; }
            set { id = value; }
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
}


Country.hbm.xml

Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
  <class name="Hcp.Domain.CountryModule.Country, Hcp.Domain" table="Country">
    <id name="Id" column="id" type="int" unsaved-value="0">
      <generator class="identity" />
    </id>
    <property name="Code" />

    <set name="CountryNames" inverse="false" lazy="false" cascade="all">
      <key column="countryId"/>
      <one-to-many class="Hcp.Domain.CountryModule.CountryName, Hcp.Domain"/>
    </set>
   
  </class>
</hibernate-mapping>


CountryName.hbm.xml

Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
  <class name="Hcp.Domain.CountryModule.CountryName, Hcp.Domain" table="CountryName">
    <id name="Id" column="id" type="int" unsaved-value="0">
      <generator class="identity" />
    </id>
    <property name="Name" />
  </class>
</hibernate-mapping>


Top
 Profile  
 
 Post subject: Re: CreateFilter and "The collection was unreferenced&q
PostPosted: Thu Feb 09, 2006 4:18 pm 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
plind wrote:
Hi

For navigating my associations with NHibernate 1.0.2, I thought I'd start of easy with a simple test of the CreateFilter operation. But before I knew it I ran into a "the collection was unreferenced" exception and I don't know what I'm doing wrong!


Seems like You never create a Set instance for countryNames field?

Gert


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 20, 2006 6:34 pm 
Newbie

Joined: Thu Feb 09, 2006 3:44 pm
Posts: 5
Hi Gert,

Thank you for your reply and sorry for my late one (I've been away for a week). Let me first say that I have a lot of programming experience, but am quite new to C#. Since my main focus lately is architecture, I like the possibilities NHibernate offers and that's why I'm diving into that at the same time as C#. Maybe a little too ambitious, but with documentation and examples, things have worked out really well... until now.

I have tried your suggestion, e.g. by casting the CountryNames in the CreateFilter to a Set, but that does not do the trick. Hopefully you can give me some more information, maybe even background on what point I'm missing here.

Thank you!

Pascal.

P.S. Somehow I have the feeling I'm missing a very basic C# point here, and I feel a little stupid for that; hope you forgive me if that''s the case.


Top
 Profile  
 
 Post subject: Not able to replicate
PostPosted: Tue Feb 21, 2006 12:19 am 
Regular
Regular

Joined: Tue Jan 03, 2006 7:21 am
Posts: 85
I tried out your example. I created 2 tables in DB

[code]
CREATE TABLE [dbo].[CountryName] (
[id] [int] IDENTITY (1, 1) NOT NULL ,
[countryId] [int] NULL ,
[Name] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[Country] (
[id] [int] IDENTITY (1, 1) NOT NULL ,
[code] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]
GO[/code]

So there is a one-to-many relationship between Country and CountryNames. I added 1 row in Country and 2 in CountryNames. Then I created the mappings and classes (copy pasted your code). I changed the GetName (I had to as I did not have Repository class) method to pass the Session Object. My GetName looks like:

[code]public string GetName(string languageCode, ISession session)
{
IQuery q = session.CreateFilter(CountryNames, "where this.Id = 1");

if (q.List().Count > 0)
{
return ((CountryName)q.List()[0]).Name;
}
else
{
return "Unknown";
}
} [/code]

And I wrote a Console Application to test this:

[code]XmlConfigurator.Configure();
Configuration cfg = new Configuration().AddAssembly("DAL");
sessionFactory = cfg.BuildSessionFactory();
ISession session = sessionFactory.OpenSession();

Country c = (Country)session.Load(typeof(Country),1);
Console.WriteLine(c.GetName("IND",session));
Console.WriteLine("Done");[/code]

The code executed without any problem. I am not able to replicate the exception that you are getting. Do you see me doing anything different?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 21, 2006 4:19 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
plind wrote:
P.S. Somehow I have the feeling I'm missing a very basic C# point here, and I feel a little stupid for that; hope you forgive me if that''s the case.


Propably - but this is too basic, so I'm not sure...:)

The mus create an instance of object before You start using it (unless You are using value type - integer, string, float, record, so on). In C# the instance is created by using "new" keyword.
So,

Code:
    public class Country : IEntity
    {
        ...
        private ISet countryNames = new HashedSet();


or You may add

Code:
if (copunryNames == null)
  countryNames = new HashedSet();


into appropriate place in Your code.

BTW, when NHibernate is restoring the object from database, it will assign a NHIbernate-specific set class instance to Your property...

Gert


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 21, 2006 3:22 pm 
Newbie

Joined: Thu Feb 09, 2006 3:44 pm
Posts: 5
Samujob and Gert,

Thank you both for your quick responses and your helping hand.

Samujob, it's great that you tried my code, thanks! Since you copied my situation, and only altered the session bit, I was able to narrow down my problem and find out what went wrong: I used a newly created repository to get my session, but the country object was already retrieved through a session in another repository object! I really paid no attention to this, since I thought I had defined my repository as a singleton (regardless if this would have been a good choice in this experiment), but something doesn't work out here the way I thought it would. So I will have to work on repository and session management. Applying the CreateFilter on the same session object with which I retrieved the country now does the job brilliantly!!

Gert, thank you too for your suggestion. I tried to see if the instantiation of a HashedSet made a difference compared to my original code for the get property of CountryNames, but it didn't. I've seen your suggested code in other people's code as well, but untill now I don't see the exact point of applying this code; I'm still unsure if there is one or if I'm missing it completely.

Cheers,

Pascal.


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