makim
makim

Reputation: 3284

NHibernate Invalid Index Exception

I´m developing an ASP.NET MVC Application, in which I use NHibernate and Ninject.

The Problem is caused by the following Controller:

public class ShoppingCartController : Controller
{
    private readonly Data.Infrastructure.IShoppingCartRepository _shoppingCartRepository;
    private readonly Data.Infrastructure.IShopItemRepository _shopItemRepository;

    public ShoppingCartController(Data.Infrastructure.IShoppingCartRepository shoppingCartController, 
        Data.Infrastructure.IShopItemRepository shopItemRepository)
    {
        _shoppingCartRepository = shoppingCartController;
        _shopItemRepository = shopItemRepository;
    }

    public ActionResult AddToShoppingCart(FormCollection formCollection)
    {
        var cartItem = new Data.Models.ShoppingCartItem();
        cartItem.ChangeDate = DateTime.Now;
        cartItem.ShopItem = _shopItemRepository.GetShopItem(SessionData.Data.Info, Convert.ToInt32(formCollection["shopItemId"]));
        //IF I DONT´T CALL THE METHOD ABOVE, AddToCart works

        _shoppingCartRepository.AddToCart(SessionData.Data.Info, cartItem);
        //BUT IF I CALL THE GetShopItem METHOD I GET THE EXCEPTION HERE!
        return RedirectToAction("Index", "Shop");
    }
}

I know most of the Time this Exception is caused by wrong Mapping, but I´m pretty sure that my Mapping is right because the AddToCart-Method works if I don´t call GetShopItem...

So here is the Code of the ShopItemRepository:

public class ShopItemRepository : ReadOnlyRepository<ShopItem>, IShopItemRepository
{
    public ShopItemRepository(IUnitOfWork uow) : base(uow)
    {

    }

    public ShopItem GetShopItem(SessionParams param, int id)
    {
        return CurrentSession.QueryOver<ShopItem>()
                       .Where(x => x.ProcessId == param.ProcessId && 
                                   x.CatalogueId == param.CatalogueId && 
                                   x.Id == id)
                       .SingleOrDefault();
    }

    public IList<ShopItem> GetShopItems(SessionParams param)
    {
        return CurrentSession.GetNamedQuery("GetShopItems")
                       .SetParameter("requestor_id", param.RequestorId)
                       .SetParameter("recipient_id", param.RecipientId)
                       .SetParameter("process_id", param.ProcessId)
                       .SetParameter("catalogue_id", param.CatalogueId)
                       .List<ShopItem>();
    }
}

And finally the Code of my UnitOfWork (basically it is just a Wrapper for the Session because I don´t want to reference NHibernate in my MVC Project)

public class UnitOfWork : IUnitOfWork, IDisposable
{
    private NHibernate.ISession _currentSession;
    public NHibernate.ISession CurrentSession
    {
        get
        {
            if(_currentSession == null)
            {
                _currentSession = SessionFactoryWrapper.SessionFactory.OpenSession();
            }
            return _currentSession;
        }
    }

    public void Dispose()
    {
        if(_currentSession != null)
        {
            _currentSession.Close();
            _currentSession.Dispose();
            _currentSession = null;
        }
        GC.SuppressFinalize(this);
    }
}

Addendum:
My NinjectWebCommon Class

public static class NinjectWebCommon 
{
    private static readonly Bootstrapper bootstrapper = new Bootstrapper();

    /// <summary>
    /// Starts the application
    /// </summary>
    public static void Start() 
    {
        DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
        DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
        bootstrapper.Initialize(CreateKernel);
    }

    /// <summary>
    /// Stops the application.
    /// </summary>
    public static void Stop()
    {
        bootstrapper.ShutDown();
    }

    /// <summary>
    /// Creates the kernel that will manage your application.
    /// </summary>
    /// <returns>The created kernel.</returns>
    private static IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

        RegisterServices(kernel);
        return kernel;
    }

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();

        kernel.Bind<Data.Infrastructure.ICatalogueRepository>().To<Data.Repositories.CatalogueRepository>();
        kernel.Bind<Data.Infrastructure.ICategoryRepository>().To<Data.Repositories.CategoryRepository>();
        kernel.Bind<Data.Infrastructure.IContactRepository>().To<Data.Repositories.ContactRepository>();
        kernel.Bind<Data.Infrastructure.IProcessRepository>().To<Data.Repositories.ProcessRepository>();
        kernel.Bind<Data.Infrastructure.IShopItemRepository>().To<Data.Repositories.ShopItemRepository>();
        kernel.Bind<Data.Infrastructure.IShoppingCartRepository>().To<Data.Repositories.ShoppingCartRepository>();
    }        
}

IUnitOfWork is set to RequestScope so in the Case of ShoppingCartController, the two Repositories share the same UOW right?

Maybe this could cause the Problem?

Upvotes: 1

Views: 78

Answers (1)

user2984186
user2984186

Reputation:

Are you sure that this isn´t caused by wrong mapping? I had the same Issue and could resolve it by checking my mappings again!

Upvotes: 1

Related Questions