views:

32

answers:

1

I have a User table defined like this:

CREATE TABLE Users(
    UserId int IDENTITY(1,1) NOT NULL,
    UserName varchar(128) NOT NULL,
    Name nvarchar(200) NOT NULL,
    Password binary(64) NOT NULL,
    PasswordSalt binary(16) NOT NULL
)

I'm trying to have two class that map to this table:

  • The first object, called User has no Password and PasswordSalt properties.
  • The second object, called SecurityUser, inherits from User and defines the Password and PasswordSalt properties.

The idea behind this is that SecurityUser is a internal object that require a intermediate service to modify the password. This is needed to avoid returning the password and salt everytime I need to query a user.

The User class is, what I call, a safe object that doesn't provide any user sensitive information.

Right now, I have defined two map:

public class UserMap : ClassMap<User>
{
    protected UserMap()
    {
        Id(x => x.Id);
        Map(x => x.UserName);
        Map(x => x.Name);
    }
}

and

public class SecurityUserMap : SubclassMap<SecurityUser>
{
    protected SecurityUserMap()
    {
        Map(x => x.Password);
        Map(x => x.PasswordSalt);
        Table("Users");
    }
}

The problem is that nHibernate creates a table called SecurityUser. I tried using the Table("Users") function to specify the same table, but I then get a invalid nhibernate mapping.

How can I achieve what I am trying to do? Or is there is an alternate approach?

+1  A: 

NHibernate does not know when to save a User and when to save a security user. You need something in your database to tell NHibernate when a record is a user, and when it is a security user. To tell you how do to that, I need to know why "This is needed to avoid returning the password and salt everytime I need to query a user."? When the reason is performance, You can probably not measure the difference. If you use the User class for reporting scenario's, you can better use a projection class to select the result of the reporting queries to, than a mapped entity.

Paco
`SR-43: Sensitive information (see glossary, SR-39) shall not be accessible when querying a user or a list of users.` Basically, this requirement exists to prevent over-the-wire tapping. Since we use nHibernate on the Data Layer, I wanted to be able to return the User without the password, while still being able to set the password on registration or change password. The `SecurityUser` was never to be returned through a service and only used internally.
Pierre-Alain Vigeant
In that case, you can better send dumb DTO's instead of complex NHibernate entities over the wire. The number of questions on stackoverflow about this subject can convince you to use DTOs instead of entities over the wire. I don't mean that it is not possible to make a good application with sending entities over the wire, but it is more difficult to create than using DTOs. With tools like automapper, you only have to define the DTO, and automapper can automatically map your entity to the DTO.
Paco