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.  [ 12 posts ] 
Author Message
 Post subject: ISession.Save doesnt work wen i use an generic repository<
PostPosted: Tue Apr 03, 2007 11:37 am 
Beginner
Beginner

Joined: Wed Mar 22, 2006 6:59 am
Posts: 30
i didnt find out what is wrong with my Repository, i have debugged it....

i have an interface IRepository<T> wich define methods like Save, Get, Delete etc..

so, i have an NHibernate implementation of IRepository, the point is the Save method:



Code:
           public void Save(T entity)
      {
            ITransaction tx = Session.BeginTransaction();
            try
            {
                Session.SaveOrUpdate(entity);
                tx.Commit();
                Session.Flush();
            }
            catch
            {
                tx.Rollback();
                throw;
            }         
      }


And also i have a static class Repository<T>. This class encapsulates my NHRepository<T>, so in Repository<T> i have:

Code:
    public static class Repository<T>
    {
        private static IRepository<T> _internalRepository = new NHRepository<T>();
        private static IRepository<T> InternalRepository
        {
            get
            {
               return _internalRepository;
            }
        }


       /// <summary>
       /// Get the entity from the persistance store, or return null
       /// if it doesn't exist.
       /// </summary>
       /// <param name="id">The entity's id</param>
       /// <returns>Either the entity that matches the id, or a null</returns>
       public static T Get(object id)
       {
          return InternalRepository.Get(id);
       }

       // other methods


when i use the Repository to save an object, just like this:

Code:
Product obj = new Product();
obj.Name = "This is a Test";

Repository<Product>.Save(obj);


My object is not saved, NHibernate just generate code for getting the next ID ( i´m using generator from Firebird database)... BUT, if in my code i call directly my SessionManager, not using Repository, my object is saved.

Please, if someone can figure out what is wrong i appreciate... is someone would like to see my code, please, just ask for... i dont know more where to look for ...

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 03, 2007 9:29 pm 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
Well, "Session.Flush()" should go before "tx.Commit()". Hope this helps.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 04, 2007 7:08 am 
Beginner
Beginner

Joined: Wed Mar 22, 2006 6:59 am
Posts: 30
unhapply,

moving session.flush had no affect :(

any, thanks for reading my post and try to help me.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 04, 2007 7:39 pm 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
Do you mind posting the implementation of NHRepository<T> ?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 09, 2007 7:01 am 
Beginner
Beginner

Joined: Wed Mar 22, 2006 6:59 am
Posts: 30
canton,

as you request, here is my implementation of repository, and bellow that, my implementation of nhibernate session manager... thanks for helping me


Code:
using System;
using System.Collections.Generic;
using System.Data;
using NHibernate;
using NHibernate.Connection;
using NHibernate.Expression;

namespace Quicoli.Commons.Repository
{
   public class NHRepository<T> : IRepository<T>
   {
      protected virtual ISession Session
      {
            get { return SessionManager.Current.GetSession(); }
      }

      public T Get(object id)
      {
         return (T)Session.Get(typeof(T), id);
      }

      public T Load(object id)
      {
         return (T)Session.Load(typeof(T), id);
      }

      public void Delete(T entity)
      {
         Session.Delete(entity);
      }

      public void Save(T entity)
      {
            ITransaction tx = Session.BeginTransaction();
            try
            {
                Session.SaveOrUpdate(entity);
                Session.Flush();
                tx.Commit();
            }
            catch
            {
                tx.Rollback();
                throw;
            }         
      }

      public ICollection<T> FindAll(Order order, params ICriterion[] criteria)
      {
         ICriteria crit = RepositoryHelper<T>.CreateCriteriaFromArray(Session, criteria);
         crit.AddOrder(order);
         return crit.List<T>();
      }

      public ICollection<T> FindAll(Order[] orders, params ICriterion[] criteria)
      {
         ICriteria crit = RepositoryHelper<T>.CreateCriteriaFromArray(Session, criteria);
         foreach (Order order in orders)
         {
            crit.AddOrder(order);
         }
         return crit.List<T>();
      }

      public ICollection<T> FindAll(params ICriterion[] criteria)
      {
         ICriteria crit = RepositoryHelper<T>.CreateCriteriaFromArray(Session, criteria);
         return crit.List<T>();
      }

      public ICollection<T> FindAll(int firstResult, int numberOfResults, params ICriterion[] criteria)
      {
         ICriteria crit = RepositoryHelper<T>.CreateCriteriaFromArray(Session, criteria);
         crit.SetFirstResult(firstResult)
            .SetMaxResults(numberOfResults);
         return crit.List<T>();
      }

      public ICollection<T> FindAll(
         int firstResult, int numberOfResults, Order selectionOrder, params ICriterion[] criteria)
      {
         ICriteria crit = RepositoryHelper<T>.CreateCriteriaFromArray(Session, criteria);
         crit.SetFirstResult(firstResult)
            .SetMaxResults(numberOfResults);
         crit.AddOrder(selectionOrder);
         return crit.List<T>();
      }

      public ICollection<T> FindAll(
         int firstResult, int numberOfResults, Order[] selectionOrder, params ICriterion[] criteria)
      {
         ICriteria crit = RepositoryHelper<T>.CreateCriteriaFromArray(Session, criteria);
         crit.SetFirstResult(firstResult)
            .SetMaxResults(numberOfResults);
         foreach (Order order in selectionOrder)
         {
            crit.AddOrder(order);
         }
         return crit.List<T>();
      }

      public ICollection<T> FindAll(string namedQuery, params Parameter[] parameters)
      {
         IQuery query = RepositoryHelper<T>.CreateQuery(Session, namedQuery, parameters);
         return query.List<T>();
      }

      public ICollection<T> FindAll(
         int firstResult, int numberOfResults, string namedQuery, params Parameter[] parameters)
      {
         IQuery query = RepositoryHelper<T>.CreateQuery(Session, namedQuery, parameters);
         query.SetFirstResult(firstResult)
            .SetMaxResults(numberOfResults);
         return query.List<T>();
      }

      public T FindOne(params ICriterion[] criteria)
      {
         ICriteria crit = RepositoryHelper<T>.CreateCriteriaFromArray(Session, criteria);
         return (T)crit.UniqueResult();
      }

      public T FindOne(string namedQuery, params Parameter[] parameters)
      {
         IQuery query = RepositoryHelper<T>.CreateQuery(Session, namedQuery, parameters);
         return (T)query.UniqueResult();
      }

      public ICollection<T> FindAll(DetachedCriteria criteria, params Order[] orders)
      {
         ICriteria executableCriteria = RepositoryHelper<T>.GetExecutableCriteria(Session, criteria, orders);
         return executableCriteria.List<T>();
      }

      public ICollection<T> FindAll(DetachedCriteria criteria, int firstResult, int maxResults, params Order[] orders)
      {
         ICriteria executableCriteria = RepositoryHelper<T>.GetExecutableCriteria(Session, criteria, orders);
         executableCriteria.SetFirstResult(firstResult);
         executableCriteria.SetMaxResults(maxResults);
         return executableCriteria.List<T>();
      }

      public T FindOne(DetachedCriteria criteria)
      {
         ICriteria executableCriteria = RepositoryHelper<T>.GetExecutableCriteria(Session, criteria, null);
         return (T)executableCriteria.UniqueResult();
      }

      public T FindFirst(DetachedCriteria criteria, params Order[] orders)
      {
         ICriteria executableCriteria = RepositoryHelper<T>.GetExecutableCriteria(Session, criteria, orders);
         executableCriteria.SetFirstResult(0);
         executableCriteria.SetMaxResults(1);
         return (T)executableCriteria.UniqueResult();
      }

      /// <summary>
      /// Find the first entity of type
      /// </summary>
      /// <param name="orders">Optional orderring</param>
      /// <returns>The entity or null</returns>
      public T FindFirst(params Order[] orders)
      {
         return FindFirst(null, orders);
      }

      /// <summary>
      /// Check if any instance matches the criteria.
      /// </summary>
      /// <returns><c>true</c> if an instance is found; otherwise <c>false</c>.</returns>
      public bool Exists(DetachedCriteria criteria)
      {
         return 0 != Count(criteria);
      }

      /// <summary>
      /// Check if any instance of the type exists
      /// </summary>
      /// <returns><c>true</c> if an instance is found; otherwise <c>false</c>.</returns>
      public bool Exists()
      {
         return Exists(null);
      }

      /// <summary>
      /// Counts the number of instances matching the criteria.
      /// </summary>
      /// <param name="criteria"></param>
      /// <returns></returns>
      public long Count(DetachedCriteria criteria)
      {
         ICriteria crit = RepositoryHelper<T>.GetExecutableCriteria(Session, criteria, null);
              crit.SetProjection(Projections.RowCount());
              object countMayBe_Int32_Or_Int64_DependingOnDatabase = crit.UniqueResult();
         return Convert.ToInt64(countMayBe_Int32_Or_Int64_DependingOnDatabase);
      }

      /// <summary>
      /// Counts the overall number of instances.
      /// </summary>
      /// <returns></returns>
      public long Count()
      {
         return Count(null);
      }
   }
}



Session manager:

Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using NHibernate;
using NHibernate.Cfg;

namespace Quicoli.Commons.Repository
{
    public class SessionManager
    {
        #region private members

        private bool _initialized = false;
        private ISessionFactory _factory;

        #endregion

        #region public properties

        /// <summary>
        /// Returns true if the SessionSource has been initialized successfully.
        /// </summary>
        public bool IsInitialized
        {
            get { return _initialized; }
        }

        #endregion

        #region singleton implementation

        private static SessionManager _current = new SessionManager();
        public static SessionManager Current
        {
            get { return _current; }
        }

        #endregion


        private SessionManager()
        {
            //prevent direct creation
        }

        /// <summary>
        /// Reads the NHibernate configuration and builds the session factory.
        /// </summary>
        public void Initialize()
        {
            Configuration cfg = new Configuration();
           
            _factory = cfg.Configure().BuildSessionFactory();

            _initialized = true;
        }

        /// <summary>
        /// Closes the current session factory.  The next call
        /// to initialize or GetSession will re-initialize the SessionSource
        /// </summary>
        public void Close()
        {
            if (_factory == null)
                return;

            _factory.Close();
            _initialized = false;
        }

        /// <summary>
        /// Gets an open NHibernate ISession for work with the database.
        /// </summary>       
        /// <returns>ISession</returns>
        public ISession GetSession()
        {
            //if we aren't initialized, do it
            if (!_initialized)
                Initialize();

            return _factory.OpenSession();
        }

        /// <summary>
        /// Gets an open NHibernate ISession (using the existing connection) for work with the database
        /// </summary>
        /// <param name="connection">An existing IDbConnection</param>
        /// <returns>ISession</returns>
        public ISession GetSession(IDbConnection connection)
        {
            //if we aren't initialized, do it
            if (!_initialized)
                Initialize();

            return _factory.OpenSession(connection);
        }

        /// <summary>
        /// Gets an open NHibernate ISession fro work with the database.
        /// </summary>
        /// <param name="interceptor">A custom interceptor to attach to the session before returning it.</param>
        /// <returns></returns>
        public ISession GetSession(IInterceptor interceptor)
        {
            if (!_initialized)
                Initialize();

            return _factory.OpenSession(interceptor);
        }

    }
}

[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 09, 2007 8:44 am 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
In Save(), you are opening a new (and different) session object for BeginTranscation(), SaveOrUpdate(), Flush().


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 09, 2007 2:18 pm 
Beginner
Beginner

Joined: Wed Mar 22, 2006 6:59 am
Posts: 30
Canton,

i didnt understand.... my Session isnt a singleton ?

If i start a transaction a new session is created ?

If so, how can i wrap my save action in a transactional context... :

Code:
try
  Save
  commit
catch
  rollback


Could you suggest a solution ?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 09, 2007 2:48 pm 
Beginner
Beginner

Joined: Wed Mar 22, 2006 6:59 am
Posts: 30
I just edited my Save method, removing tha transactions. Now i have only

Session.SaveOrUpdate(obj)

and for my sadness...... is not working....


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 09, 2007 9:30 pm 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
Perhaps I did not make it clearly.

Replace your Save method with this
Code:
      public void Save(T entity)
      {
            ISession session = Session;
            ITransaction tx = session.BeginTransaction();
            try
            {
                session.SaveOrUpdate(entity);
                session.Flush();
                tx.Commit();
            }
            catch
            {
                tx.Rollback();
                throw;
            }         
      }


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 09, 2007 9:32 pm 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
The SessionManager.Current is a singleton, but SessionManager.Current.GetSession() is not.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 10, 2007 7:00 am 
Beginner
Beginner

Joined: Wed Mar 22, 2006 6:59 am
Posts: 30
Canton,

you´re THE man ! Really thanks !!!

Do you think i should, in others methods like Delete, do as you showed ?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 10, 2007 9:32 pm 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
I agree. To further enhance the readability/maintainability, I will replace the Session property with a GetSession() method in NHRepository<T>. This small change will stop me (and my colleagues) from making the same mistake.


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