-->
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.  [ 5 posts ] 
Author Message
 Post subject: NonUniqueObjectException in unit tests
PostPosted: Tue Sep 19, 2006 12:18 pm 
Beginner
Beginner

Joined: Wed May 31, 2006 9:24 am
Posts: 22
Hibernate version: 1.0.2.0

Mapping documents:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" namespace="TranslateHelper.Domain.Classes" assembly="TranslateHelper.Domain" default-access="field.camelcase">
   <class name="Area" table="Area">
      <jcs-cache usage="read-write" />
      <id name="Id" column="AreaId" type="Int32" unsaved-value="0">
         <generator class="identity" />
      </id>
      <property name="Name" column="Name" type="String" not-null="true" />
      <property name="Description" column="Description" type="String" not-null="true" />
      <property name="Number" column="Number" type="int" not-null="true" />
      <property name="Date" column="Date" type="DateTime" not-null="true" />
      <property name="CheckBox" column="CheckBox" type="boolean" not-null="true" />
      <bag name="Elements" table="Element" lazy="true" cascade="none">
         <key column="AreaId" />
         <many-to-many class="Element" column="ElementId" />
      </bag>
   </class>
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():
Code:
public Area CreateArea()
        {
            Area a = new Area();
            a.Name = "test";
            a.Description = "test";
            a.Number = 1;
            a.Date = new DateTime(1900, 1, 1);
            a.CheckBox = false;

            Repository.Instance.ActiveSession.SaveOrUpdateCopy(a);
            Repository.Instance.ActiveSession.Flush();
            Repository.Instance.ActiveSession.Evict(a);
            return a;
        }

        public static void Compare(Area expected, Area candidate)
        {
            Assert.AreEqual(expected.Id, candidate.Id, "Id differs");
            Assert.AreEqual(expected.Name, candidate.Name, "Name differs");
            Assert.AreEqual(expected.Number, candidate.Number, "Number differs");
            Assert.AreEqual(expected.Description, candidate.Description, "Description differs");
            Assert.AreEqual(expected.CheckBox, candidate.CheckBox, "CheckBox differs");
            Assert.AreEqual(expected.Date, candidate.Date, "Date differs");
            //Assert.AreSame(expected.Elements, candidate.Elements, "Elements differs");
        }

        #endregion

        #region Tests
        [Test]
        public void Create()
        {
            Area a = CreateArea();
            Assert.IsNotNull(a);
            Assert.AreEqual(1, a.Id);
        }

        [Test]
        public void LoadById()
        {
            //create an Area
            Area a = CreateArea();
           
            // Go get another copy of it
            Area b = Repository.AreaById(a.Id);
            Compare(a, b);
        }

        [Test]
        public void LoadAll()
        {
            //should be empty initially
            IList all = Repository.GetAll("Area");
            Assert.AreEqual(all.Count, 0);

            //create a couple of Areas to test
            Area a = CreateArea();
            Area b = CreateArea();

            all = Repository.GetAll("Area");
            Assert.AreEqual(all.Count, 2);
        }

        [Test]
        public void BulkTest()
        {
            //should be empty initially
            IList all = Repository.GetAll("Area");
            Assert.AreEqual(all.Count, 0);

            //create Area objects in bulk, and test that the ids are correctly created
            int iStartId = -1;
            for (int x = 0; x < 1000; x++)
            {
                Area a = CreateArea();
                if (iStartId == -1)
                    iStartId = a.Id;

                Assert.AreEqual(a.Id, iStartId + x, String.Format("Id's differed on loop {0}", x));
            }
        }
        #endregion
    }


Full stack trace of any exception that occurs:
TranslateHelper.Domain.Test.AreaFixture.LoadById : NHibernate.NonUniqueObjectException : a different object with the same identifier value was already associated with the session: 1, of class: TranslateHelper.Domain.Classes.Area

Name and version of the database you are using:
SQL Server 2000

I am writing some unit tests for my web app. I have included the code of the unit tests above. I have an onsetup method for my tests, so between each one, I truncate the DB table containing the Area objects, and re-seed it so that the identity starts from 1 again.

The tests run in the following order:
BulkTest()
Create()
LoadAll()
LoadById()

The first 3 tests all run fine. The 4th test gives me the NonUniqueObjectException error. I could understand this if I got the error on the 2nd and 3rd tests, since the Area object of ID 1 is being created in all of the tests, but the first 3 tests fine. The error only occurs on the 4th test. I have tried every method of clearing the session I can find, and also using the SaveOrUpdateCopy() call as reccommended by the docs, but nothing helps.

If anyone could help explain this behaviour to me I would be most grateful!

Regards, Ben


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 19, 2006 1:43 pm 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
Well, You should (must) clear the second level cache as well between tests...

BTW, the best way to have clean Session is to create a new one...

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 20, 2006 4:42 am 
Beginner
Beginner

Joined: Wed May 31, 2006 9:24 am
Posts: 22
Hi gert, I am not using a second-level cache at the moment.

I have implemented a method of creating a new session which seems to fix the problem.

I'm still not sure why it was happening though, and since in my production code I will not be creating a new session (I am using the session-per-request model, with a thread-safe lazy singleton instantiation of the session), it leaves a little worry in my mind. Basically, the more I can understand about NHibernate the better, as I wish to use it going forward, but at the moment it is a little like a 'black-box' piece of software to me...

Thanks for the guidance!

Ben


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 20, 2006 5:06 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
mustapha wrote:
Hi gert, I am not using a second-level cache at the moment.


As You mapping mentioned <jcs-cache usage="read-write" /> , I thought You use one...

mustapha wrote:
I have implemented a method of creating a new session which seems to fix the problem.

I'm still not sure why it was happening though, and since in my production code I will not be creating a new session (I am using the session-per-request model, with a thread-safe lazy singleton instantiation of the session), it leaves a little worry in my mind. Basically, the more I can understand about NHibernate the better, as I wish to use it going forward, but at the moment it is a little like a 'black-box' piece of software to me...


In production code, You will not be truncating the table, so duplicate Id-s would not be case, right?

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 20, 2006 5:14 am 
Beginner
Beginner

Joined: Wed May 31, 2006 9:24 am
Posts: 22
this is true ;)

The jcs-cache thing - I have taken the mapping document from elsewhere - I am still an NHibernate newbie, so I just left this as I found it. However, there is no caching defined in my web.config. I will go and investigate the jcs-cache thing now!

Many thanks for your help :)

Ben


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