tags:

views:

423

answers:

1

Hello. I'm having a problem: I have User:

[Class(Table = "Users", Name = "User")]
public class User
{
    [Id(0, Column = "UserId", Type = "Guid", Name = "Id")]
    [Generator(1, Class = "assigned")]
    public Guid Id { get; set; }

    [Property(Name = "Password", Column = "Password", Type = "String")]
    public string Password { get; set; }

    [Property(Name = "Email", Column = "Email", Type = "String")]
    public string Email { get; set; }
}

And a ditributor:

 [JoinedSubclass(ExtendsType = typeof(User), Table = "Distributors")]
public class Distributor : User
{

    [Id(0, Column = "DistributorId", Type = "Guid", Name = "Identifier")]
    [Generator(1, Class = "assigned")]
    protected Guid Identifier { get; set; }

    [Property(Name = "Company", Column = "Company", Type = "String")]
    public String Company { get; set; }
}

Now I need to promote user to distributor. But I need to save his id (other parts of the system are using it). I'm getting user and creating new distributor. But when I'm trying to save distributor I'm getting this error:

a different object with the same identifier value was already associated with the session: ec6f6a9f-a236-4385-835c-7f408a5f594d, of entity: MLMCore.Entities.Distributor

I have tryed all the methods (save, SaveOrUpdade, SaveOrUpdateCopy, Update). But it doesn't works. Any ideas how to fix it?

+1  A: 

The error is what it says - your session contains an instance of User with that Id, so when you try to save another User (a Distributor) with that Id, NHibernate complains. You could try clearing your session (session.Clear()) before saving the Distributor, but I don't know if NHibernate will be successful in saving to the User and the Distributor table suddenly.

If you are in a position to change your design, I suggest you do that - generally, you shouldn't use inheritance when the type of your specialization could change. It's much better and more convenient to introduce some kind of Role in your domain.

Perhaps I can give you some inspiration, even though I don't know the specifics of your domain: How about letting users be just that - instances of User. And then, User might container an IList<Role> and you could specialize Role into e.g. Distributor (and other roles if that's relevant)?

Or how about letting your company contain an IList<Distributor>, each pointing to to a User?

mookid8000
Roles are present in design. But I need additional fields for distributor. And inheritance is used to make user entity wider
I see. But why not make your role abstract then, and accompany the specializations with any data specific for that role?
mookid8000
Unfortunately its impossible to change the design, I need to find solution in this situation :(
That's too bad. I don't know if this scenario is at possible at all while still behaving "nice". Did you try clearing the session before saving and flushing your Distributor?
mookid8000
If all fails, you could issue some ugly SQL to insert a row in your Distributor table (assuming table-per-subclass inheritance strategy), thus tricking NHibernate.
mookid8000
As a temporary decision they inserted some SQL.(Sly cannot comment any more :D )
AlfeG