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.  [ 7 posts ] 
Author Message
 Post subject: NHibernate save no error but not really saved in db
PostPosted: Tue Feb 12, 2008 11:38 am 
Newbie

Joined: Tue Feb 12, 2008 11:33 am
Posts: 3
Hi,

I would like to write a common utility for saving domain object to database show as below, but when I use nunit to test it, the result is fail, I don't know where I got wrong, dose anyone can help me?

Thanks.
Code:
namespace NHibernateUtility
{
    public class NHibernateDao<T, IdT> : IDao<T, IdT>
    {
        private ISessionFactory m_factory;
        private ISession m_session;
        private NHibernate.ITransaction m_transaction;

        public NHibernateDao(ISessionFactory factory)
        {
            m_factory = factory;
        }

        public NHibernateDao(ISession session, NHibernate.ITransaction transaction)
        {
            m_session = session;
            m_transaction = transaction;
        }

        private void Open()
        {
            if (m_session == null)
            {
                if (m_factory == null) throw new NullReferenceException("Factory cannot be empty.");
                m_session = m_factory.OpenSession();
            }
        }
        private void Close()
        {
            if (m_transaction == null)
            {
                m_session.Close();
                m_session = null;
            }
        }

        public System.Collections.IList GetAll()
        {
            Open();
            ICriteria criteria = m_session.CreateCriteria(typeof(T));
            Close();
            return criteria.List<T>() as List<T>;
        }

        public Object GetById(Object id)
        {
            return LoadById((IdT)id);
        }

        public T GetById(IdT id)
        {
            return LoadById(id);
        }

        private T LoadById(IdT id)
        {
            Open();
            T t = (T)m_session.Get(typeof(T), id);
            Close();
            return t;
        }

        public bool IsExist(T entity)
        {
            return GetById((IdT)((object)entity.ToString())) != null;
        }

        public IdT Save(T entity)
        {
            Open();
            IdT id = (IdT) m_session.Save(entity);
            Close();
            return id;
        }

        public void Update(T entity)
        {
            Open();
            m_session.Update(entity);
            Close();
        }

        public void Delete(T entity)
        {
            Open();
            m_session.Delete(entity);
            Close();
        }
    }
}


Test Case
Code:
        [Test]
        public void SaveTest()
        {
            Cat cat = new Cat();
            cat.Id = "C001";
            cat.Name = "Tim Tim";
            cat.Sex = 'M';
            cat.Weight = 1.1f;

            NHibernateDao<Cat, string> dao = new NHibernateDao<Cat, string>(m_factory);
            string catId = dao.Save(cat);
            Assert.AreEqual(catId, cat.Id);

            Cat cat2 = dao.GetById("C001");
            Assert.IsNotNull(cat2);
            Assert.AreEqual(cat.Name, cat2.Name);
        }

        [Test]
        public void UpdateTest()
        {
            Cat cat1;
            NHibernateDao<Cat, string> dao = new NHibernateDao<Cat, string>(m_factory);
            cat1 = dao.GetById("CAT001");
            Assert.IsNotNull(cat1);

            cat1.Name = "Tim Tim";
            dao.Update(cat1);

            Cat cat2;
            cat2 = dao.GetById("CAT001");
            Assert.IsNotNull(cat2);

            Assert.AreEqual(cat1.Id, cat2.Id);
            Assert.AreEqual(cat1.Name, cat2.Name);
            Assert.AreEqual(cat1.Sex, cat2.Sex);
            Assert.AreEqual(cat1.Weight, cat2.Weight);
        }


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 12, 2008 1:42 pm 
Regular
Regular

Joined: Tue Dec 25, 2007 3:41 pm
Posts: 57
Location: Argentina
The exception please. We can do nothing without it.

_________________
Dario Quintana


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 12, 2008 9:43 pm 
Newbie

Joined: Tue Feb 12, 2008 11:33 am
Posts: 3
I am sorry for that there is only assertion exception found.

When I execute the test case, I found that no hibernate exception throw but my domain object have not been save or update into database.

But if I load object from database, it's work.

So I cannot indicate what the problem is.

e.g. In the test case, when I changed the cat.Name to "Tim Tim", the cat1 haven't been updated in database, it only load the old record back.

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 12, 2008 9:52 pm 
Regular
Regular

Joined: Tue Dec 25, 2007 3:41 pm
Posts: 57
Location: Argentina
Sorry, I didn't see it, you forgot the Commit or Flush to the object go to the Db.

For now, with Flush is fine, but later NH go to same behavior that Hibernate does: All CRUD operations must be between transactions.

Best regards

_________________
Dario Quintana


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 13, 2008 12:07 pm 
Newbie

Joined: Tue Feb 12, 2008 11:33 am
Posts: 3
Oh! I missed flush it into database.

But I have a question, if I haven't commit the transaction, can I load that record back?

e.g. assume the following haven't compile error, if normal SQL update and query within a transaction, it can read that updated but not committed object back to program, and I tried that if I haven't flush it when it's within a transaction, it cannot load the right object to me, do I need to flush it within a transaction?>

Code:
ITransaction tx = m_session.BeginTransaction();

dao.Update(cat1);

Cat cat2 = dao.GetById(cat1.Id);


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 13, 2008 1:13 pm 
Newbie

Joined: Wed Jan 30, 2008 4:43 pm
Posts: 9
Location: Bend, OR
From what I understand, the session does a flush behind the scenes when it needs to query the database. Which means the test should have worked. Maybe I'm missing something here...

I noticed that in SaveTest you set the Id to "C001". NHibernate will usually generate an insert sql statement if the id is blank, and an update if the id has a value. This depends on the mapping file and configuration, but is the common way it operates.

You could try turning show_sql on to get a bunch of logging info from NHibernate. (or use SQL Server Profiler if this happens to be on a SQL Server database.)

The only problem I can see with UpdateTest is that if the data isn't in the database before the test runs, it will fail on the 4th line.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 13, 2008 6:26 pm 
Regular
Regular

Joined: Tue Dec 25, 2007 3:41 pm
Posts: 57
Location: Argentina
A transaction, is a transaction. The Get will return the "old" value, because NH keep track of them.

_________________
Dario Quintana


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