简体   繁体   中英

How to execute update in NHibernate?

I'm trying execute update to object but it always throws an exception illegally attempted to associate a proxy with two open session . I can make insert but update I can't.

How could I solve it ?

DBConnect

    public class DBConnect {

            private static ISessionFactory session;
            private const String HOST = "localhost";
            private const String USER = "root";
            private const String PASSWORD = "";
            private const String DB = "pubcontrol";

            /** create a connection with database */
            private static ISessionFactory createConnection() {

                if (session != null)
                    return session;

                //database configs
                FluentConfiguration _config = Fluently.Configure().Database(MySQLConfiguration.Standard.ConnectionString(
                                                                           x => x.Server(HOST).
                                                                              Username(USER).
                                                                              Password(PASSWORD).
                                                                              Database(DB)
                                                                            ))
                                                                            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<PerfilMap>())
                                                                            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<ModuloMap>())
                                                                            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<PermissaoMap>())
                                                                            .ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(false, true));

                session = _config.BuildSessionFactory();
                return session;
            }


            /** open a session to make transactions */
            public static ISession openSession() {
                return createConnection().OpenSession();
            }
        }

GenericDAO

public class GenericDAO<T> : IPersist<T> where T : class {

        public void insert(T obj) {
            ISession _session = DBConnect.openSession();
            ITransaction _transaction = _session.BeginTransaction();
            try {
                _session.Save(obj);
                _transaction.Commit();
            }catch (Exception e) {
                if (!_transaction.WasCommitted) {
                    _transaction.Rollback();
                }
                MessageBox.Show("Erro tentando salvar: " + e.Message, "Aviso",
                MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }


        public void update(T obj) {
            ISession _session = DBConnect.openSession();
            ITransaction _transaction = _session.BeginTransaction();
            try {
                _session.Update(obj);
                _transaction.Commit();
            }catch (Exception e) {
                if (!_transaction.WasCommitted) {
                    _transaction.Rollback();
                }
                MessageBox.Show("Erro tentando alterar: " + e.Message, "Aviso", 
                MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }



        public void delete(T obj) {
            ISession _session = DBConnect.openSession();
            ITransaction _transaction = _session.BeginTransaction();
            try {
                _session.Delete(obj);
                _transaction.Commit();
            }catch (Exception e) {
                if (!_transaction.WasCommitted) {
                    _transaction.Rollback();
                }
                MessageBox.Show("Erro tentando deletar: " + e.Message, "Aviso", 
                MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }



        public T findObject(long id) {
            ISession _session = DBConnect.openSession();
            return _session.Load<T>(id);
        }


        public void saveOrUpdate(T obj) {
            ISession _session = DBConnect.openSession();
            ITransaction _transaction = _session.BeginTransaction();
            try {
                _session.SaveOrUpdate(obj);
                _transaction.Commit();
            }catch (Exception e) {
                if (!_transaction.WasCommitted) {
                    _transaction.Rollback();
                }
                MessageBox.Show("Erro tentando salvar ou alterar: " + e.Message, "Aviso",
                MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }

PermissaoDAO

public class PermissaoDAO : GenericDAO<Permissao> {

        public IList<Permissao> findAll() {
            ISession _session = DBConnect.openSession();
            IList<Permissao> list = _session.CreateQuery("FROM Permissao p")                
                .List<Permissao>();
            return list;
        }


        /** verifica se o perfil ou o modulo estao adicionados */
        public Boolean isExistPerfilAndModulo(Permissao permissao) {
            ISession _session = DBConnect.openSession();
            IList<Permissao> list = _session.CreateQuery("FROM Permissao p WHERE p.perfil = :p AND p.modulo = :m")
                .SetParameter("p", permissao.perfil)
                .SetParameter("m", permissao.modulo)
                .List<Permissao>();
            if (list.Count > 0) {
                return true;
            }
            return false;
        }

        /** retorna a permissao */
        public Permissao getPermissao(Permissao permissao) {
            ISession _session = DBConnect.openSession();
            IList<Permissao> list = _session.CreateQuery("FROM Permissao p WHERE p.perfil = :p AND p.modulo = :m").SetMaxResults(1)
                .SetParameter("p", permissao.perfil)
                .SetParameter("m", permissao.modulo)
                .List<Permissao>();
            return list[0];
        }


    }

Making Update

/** insere Perfil + Modulo */
        private void insertPerfilModulo() {
            PermissaoDAO dao = new PermissaoDAO();
            Perfil perfil = (Perfil)cbxPerfilModulo.SelectedItem;
            IList<Modulo> lista = getListaModulo();

            foreach(Modulo m in lista){                
                Permissao permissao = new Permissao();
                permissao.perfil = perfil;
                permissao.modulo = m;

                Boolean exist = dao.isExistPerfilAndModulo(permissao);                
                if (exist) {
                    Permissao p = dao.getPermissao(permissao);
                    dao.update(p);
                }else {
                    dao.insert(permissao);
                }
            }
        }

You should not use multiple sessions with the same object. You should not create a transaction for every single database operation, this way transaction do not make any sense. Have each a session and transaction span the whole business operation and don't forget to close (or dispose) both at the end.

Update is implicit for every object within the session. Every object that had been queried or inserted is managed by the session.

When using NHibernate, code usually looks like this (exemplary, can look very different depending on how you design your DAO, but the concept should be the same):

using (session = dao.CreateSession())
using (session.CreateTransaction())
{
  var myObject = dao.Get<MyObject>(id);
  if (myObject == null)
  {
    myObject = new MyObject();
    dao.Insert(myObject);
  }
  myObject.Property = 3;
  dao.Commit();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM