views:

106

answers:

2

HEllo,

I'm using nhibernate and have problems regarding user registration on my site.

When user wants to register I create new user record in the database and immidiatelly after that the system is logging the user in.

Well here lies the problem... When creating user record I'm using

NHibernateSession.Save(entity); //does not saves user object immediately to the database. It's kept in the session.

And when I want to log the user in, i load the user by his user name, and then I get null user object.

Why am I getting a null object and how can I make it work?

Thanks

+1  A: 

If your Save and Get are done from different sessions then the Get will return null because the object only exists in the other sessions internal cache until it is flushed.

I'm not sure if an L2 cache would make a difference (I don't if L2 cache is written at Save or Flush).

eyston
I went into debug mode and checked session IDs (on save and get) and they are the same.
Goran
odd... would have to do some testing to see what makes sense.
eyston
+3  A: 

Ok, I just tested this :

        ISession session = s.CreateSession();

  User user = new User();

  user.Number = 122;
  user.UserName = "u";
  user.Id = 1;

  session.Save(user);
  User user1 = session.CreateCriteria<User>().Add(Restrictions.Eq("UserName", "u")).UniqueResult<User>();

  session.Flush();

First the Select is being executed from the CreateCriteria and then on Flush the insert. So that's why it's not finding anything.

I also tested with Get<User>(1) and it returns the entity passed to the Save method - no query is executed.

Still - why query the database since you have the entity right there ?

Also, you say you use Get and then say you want to load by the UserName - is the UserName the primary key ? Get tries to load by the primary key.

sirrocco
From Ayende blog (http://ayende.com/Blog/archive/2009/04/30/nhibernate-ndash-the-difference-between-get-load-and-querying-by.aspx): "Get will usually result in a select against the database, but it will check the session cache and the 2nd level cache first to get the values first." I take this to mean if you have a Save() and Get() right after another for same entity it shouldn't hit the db, but I haven't taken the time to test yet.
eyston
hmm.. you might be right - but I still don't understand why call get when you have the entity right there.
sirrocco
Yah, I think more info is needed.
eyston
Still - why query the database since you have the entity right there ?Well, becase this is all happening in conjunction with my custom asp.net Membership provider... and it's a use case of registering a new user... When you register a new user you save it to the database and return Membership user object back to the register control. Immediately after that the control is invoking Validate method of Membership provider passing just username and password in order to validate user (log him in). You use that username and password in order to load user object, you just saved few moments ago.
Goran
It is querying the database because you are doing a query not on the id of the entity but on a username/password. NH has to go to the db. The other thing it sounds like 'Registration' and 'Validation' should be their own Units of Work wrapped in a transaction (or at least a flush).
eyston
I think he's doing something like : repository.Save(user) - Membership.GetUser(username) . Probably some code would cast more light on the matter.
sirrocco