Reputation: 4460
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);
}
}
}
Upvotes: 0
Views: 1149
Reputation: 64628
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();
}
Upvotes: 1