Many to Many Problems

47 views
Skip to first unread message

Fabricio Martinez

unread,
Apr 14, 2012, 8:22:45 PM4/14/12
to nhu...@googlegroups.com
Hello,

Im having problems using the many to many features in NHBibernate. My problem is that I cant add an item to an already created object. The only way for it to work I have to create everything new in the same ISession. Am I doing it wrong or is this how it works?

my application is developed under Asp.NET MVC 4 with autofac. I'm using the repository and unit of work pattern.

My objects are the following:

    [DataContract(IsReference = true)]

    [KnownType(typeof(Provincia))]

    [KnownType(typeof(CodigoPostal))]

    public partial class Localidad

    {

        [DataMember]

        public virtual int Id  { get; set; }


        [DataMember]

        public virtual string Nombre  { get; set; }


        [DataMember]

        public virtual Provincia Provincia  { get; set; }

        

        [DataMember]

        public virtual IList<CodigoPostal> CodigoPostal { get; set; }

    }


    [DataContract(IsReference = true)]

    [KnownType(typeof(Localidad))]

    public partial class CodigoPostal

    {

        [DataMember]

        public virtual int Id { get; set; }


        [DataMember]

        public virtual string Codigo { get; set; }


        [DataMember]

        public virtual IList<Localidad> Localidad  { get; set; }

    }


My mappings:


    public partial class CodigoPostalMap : ClassMap<CodigoPostal>

    {

        public CodigoPostalMap()

        {

            Id(x => x.Id).GeneratedBy.Identity();

            Map(x => x.Codigo).Length(5).Not.Nullable();

            HasManyToMany(x => x.Localidad).Inverse().LazyLoad().Cascade.SaveUpdate();

        }

    }


    public partial class LocalidadMap : ClassMap<Localidad>

    {

        public LocalidadMap()

        {

            Id(x => x.Id).GeneratedBy.Identity();

            Map(x => x.Nombre).Length(100).Not.Nullable();

            References(x => x.Provincia).Not.Nullable();

            HasManyToMany(x => x.CodigoPostal).LazyLoad().Cascade.SaveUpdate();

        }

    }



Oskar Berggren

unread,
Apr 15, 2012, 3:41:03 AM4/15/12
to nhu...@googlegroups.com
And the failing code?

/Oskar

> --
> You received this message because you are subscribed to the Google Groups
> "nhusers" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/nhusers/-/dLVeVjIHsj8J.
> To post to this group, send email to nhu...@googlegroups.com.
> To unsubscribe from this group, send email to
> nhusers+u...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/nhusers?hl=en.

Fabricio Martinez

unread,
Apr 15, 2012, 6:30:23 AM4/15/12
to nhu...@googlegroups.com
My Unit Test Code:

[TestClass()]

    public class LocalidadTest

    {

        private TestContext testContextInstance;

        private IContainer container;


        public LocalidadTest()

        {

            HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize();


            var builder = new ContainerBuilder();


            builder.Register(c => iSeguro.Data.Infrastructure.ConnectionHelper.BuildSessionFactory()).As<ISessionFactory>().SingleInstance();

            builder.Register(c => c.Resolve<ISessionFactory>().OpenSession()).InstancePerLifetimeScope();


            builder.RegisterControllers(Assembly.GetExecutingAssembly());

            builder.RegisterType<DefaultCommandBus>().SingleInstance();

            builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();


            builder.RegisterAssemblyTypes(typeof(IRepository<Pais>).Assembly).Where(t => t.Name.EndsWith("PaisRepository")).AsImplementedInterfaces().InstancePerLifetimeScope();

            builder.RegisterAssemblyTypes(typeof(IRepository<Provincia>).Assembly).Where(t => t.Name.EndsWith("ProvinciaRepository")).AsImplementedInterfaces().InstancePerLifetimeScope();

            builder.RegisterAssemblyTypes(typeof(IRepository<Localidad>).Assembly).Where(t => t.Name.EndsWith("LocalidadRepository")).AsImplementedInterfaces().InstancePerLifetimeScope();

            builder.RegisterAssemblyTypes(typeof(IRepository<CodigoPostal>).Assembly).Where(t => t.Name.EndsWith("CodigoPostalRepository")).AsImplementedInterfaces().InstancePerLifetimeScope();

            builder.RegisterAssemblyTypes(typeof(IRepository<CodigoPostalLocalidad>).Assembly).Where(t => t.Name.EndsWith("CodigoPostalLocalidadRepository")).AsImplementedInterfaces().InstancePerLifetimeScope();


            var services = Assembly.Load("iSeguro.Domain");

            builder.RegisterAssemblyTypes(services).AsClosedTypesOf(typeof(ICommandHandler<>)).InstancePerLifetimeScope();

            builder.RegisterAssemblyTypes(services).AsClosedTypesOf(typeof(IValidationHandler<>)).InstancePerLifetimeScope();

            builder.RegisterFilterProvider();


            container = builder.Build();

        }


        [TestMethod()]

        public void LocalidadAddCodigoTest()

        {

            using (var lifetime = container.BeginLifetimeScope())

            {

                ILocalidadRepository localidadRepository = lifetime.Resolve<ILocalidadRepository>();

                ICodigoPostalRepository codigoRepository = lifetime.Resolve<ICodigoPostalRepository>();


                DefaultCommandBus commandBus = lifetime.Resolve<DefaultCommandBus>();

                commandBus.Container = this.container;


                Localidad localidad = localidadRepository.Get(c => c.Nombre == "TEST");

                Assert.IsNotNull(localidad, "Error: Localidad is null");


                CodigoPostal codigo = codigoRepository.Get(x => x.Codigo == "TEST");

                Assert.IsNotNull(codigo, "Error: Codigo Postal is null");


                localidad.CodigoPostal = new List<CodigoPostal>();

                localidad.CodigoPostal.Add(codigo);


                CreateOrUpdateLocalidadCommand command = new CreateOrUpdateLocalidadCommand(localidad);


                ICommandResult result = commandBus.Submit(command);

                Assert.IsNotNull(result, "Error:Localidad Was Not Created by CommandBus");

                Assert.IsTrue(result.Success, "Error: Localidad Was Not Created by CommandBus");

            }

        }

    }


Repository:

    public abstract class RepositoryBase<T> where T : class

    {

        private readonly ISession session;


        public RepositoryBase(ISession session)

        {

            this.session = session;

            this.session.FlushMode = FlushMode.Auto;

        }


        public bool Add(T entity)

        {

            this.session.Save(entity);

            return true;

        }


        public bool Add(IEnumerable<T> items)

        {

            foreach (T item in items)

            {

                this.session.Save(item);

            }

            return true;

        }


        public bool Update(T entity)

        {

            this.session.Update(entity); //It fails here stating that there is an object already with the same key.

            return true;

        }


        public bool Delete(T entity)

        {

            this.session.Delete(entity);

            return true;

        }


        public bool Delete(IEnumerable<T> entities)

        {

            foreach (T entity in entities)

            {

                this.Delete(entity);

            }

            return true;

        }


        public T GetById(int id)

        {

            return this.session.Get<T>(id);

        }


        public T GetById(string id)

        {

            return this.session.Get<T>(id);

        }


        public T GetById(long id)

        {

            return this.session.Get<T>(id);

        }


        public IQueryable<T> GetAll()

        {

            return this.session.Query<T>();

        }


        public T Get(Expression<System.Func<T, bool>> expression)

        {

            return GetMany(expression).SingleOrDefault();

        }


        public IQueryable<T> GetMany(Expression<System.Func<T, bool>> expression)

        {

            return GetAll().Where(expression).AsQueryable();

        }


    }


Unit of work:

public class UnitOfWork : IUnitOfWork

    {

        private readonly ISession Session;

        private readonly ITransaction transaction;


        public UnitOfWork(ISession session)

        {

            this.Session = session;

            this.Session.FlushMode = FlushMode.Auto;

            this.transaction = Session.BeginTransaction(IsolationLevel.ReadCommitted);

        }


        ~UnitOfWork()

        {

            this.Dispose();

        }


        public void Dispose()

        {

            this.Session.Close();

        }


        public void Commit()

        {

            if (!this.transaction.IsActive)

            {

                throw new InvalidOperationException("No active transation");

            }

            this.transaction.Commit();

        }


        public void Rollback()

        {

            if (this.transaction.IsActive)

            {

                this.transaction.Rollback();

            }

        }

    }


Finally the command:

public class CreateOrUpdateLocalidadHandler : ICommandHandler<CreateOrUpdateLocalidadCommand>

    {

        private readonly ILocalidadRepository localidadRepository;

        private readonly IUnitOfWork unitOfWork;


        public CreateOrUpdateLocalidadHandler(ILocalidadRepository localidadRepository, IUnitOfWork unitOfWork)

        {

            this.localidadRepository = localidadRepository;

            this.unitOfWork = unitOfWork;

        }


        public ICommandResult Execute(CreateOrUpdateLocalidadCommand command)

        {

            var localidad = new Localidad

            {

                Id = command.Id,

                Nombre = command.Nombre,

                Provincia = command.Provincia,

                CodigoPostal = command.CodigoPostal

            };


            if (localidad.Id == 0) localidadRepository.Add(localidad); else localidadRepository.Update(localidad);

            unitOfWork.Commit();

            return new CommandResult(true);

        }

    }

Reply all
Reply to author
Forward
0 new messages