views:

24

answers:

2

Hello all,

The entities and mappings I'm talking about in this question can be found here :)

Here is the context:

I have a parent view-model which helps to manage some entities, and which has its own session.

From this VM, I open another view-model (with its own session too), do some changements to the entity (add and/or remove children), and when I validate the changements, I commit the session and warns the first view-model to refresh the display:

public void Validate()
{
    using (var tx = Session.BeginTransaction())
    {
        try
        {
            SelectedTeam.ClearRoster();

            foreach (var teamPlayer in TeamPlayers)
                SelectedTeam.AddPlayer(teamPlayer);

            teamsRepository.SaveOrUpdate(SelectedTeam);

            tx.Commit();
        }
        catch (Exception ex)
        {
            tx.Rollback();
        } 
        finally
        {
            if (tx.WasCommitted)
                ServiceLocator.Current.GetInstance<Mediator>().NotifyColleagues(MediatorMessages.DisplayEntityInfos, SelectedTeam.Id);
        }
    }
}

Here is the faulted method of the parent VM:

public void RefreshEntitiesListAndDisplayEntityInfos(int selectedEntityId)
{
    TEntity entity = entitiesRepository.Load(selectedEntityId);
    Session.Refresh(entity);
    //...
}

The exception is thrown at the Refresh line:

NHibernate.UnresolvableObjectException

And the message is:

No row with the given identifier exists[Emidee.CommonEntities.PlayerInTeam#3

I can open and change the entity multiple times, but it seems that the exception is thrown when I delete a children, then add another one, and finally delete another one.

After some readings on the web, it seems that's because when I refresh the entity, and because I changed the HasMany relationship (because I have deleted a player for example), NH tries to reload the deleted row.

I've tried to add a NotFound.Ignore statement on the HasMany in my mappings, I've tried to force a new query to the DB instead of a Load, but I still get this exception.

Does someone know how I could fix that?

Thanks in advance

Mike

+1  A: 

This is a known behavior when refreshing objects with modified collections.

To force reload, change your method to do session.Evict with the entity as a parameter. This is the code we use in our base model class:

public T ReGet<T>(T entity) where T : IEntity
{
    var id = entity.Id;
    Session.Evict(entity);
    return Session.Get<T>(id);
}
Diego Mijelshon
A: 

Well, I've just spotted the problem.

To update the players list of the team, I used to clear the list, and add the new players, before updating the entity.

Now, I update the list by removing and adding only the players who have been moved by the user, and I don't have any problems at all now.

That's weird. I don't know what was wrong before, but as least that works now.

Mike