tags:

views:

229

answers:

5

Hi

I'm writing an application and started to test my domain model entities. If I Create an instance of entity Company like this var company = new Company("my company"); I should get a valid entity, meaning the company should at this moment have an Id correct?

So the problem is that at the moment I have the Id generation made in the DB defined in an hbm file like this:

<id name="ObjectIdentity" column="CompanyId" type="System.Guid" unsaved-value="00000000-0000-0000-0000-000000000000">
  <generator class="guid.comb"/>
</id>

This causes a problem when writing unittests as I do not have en entity with an Id as it dosen't touch the db in the test, aka I have an invalid entity.

Now should I assign Id in the application and not let nhibernate be in charge of this or is this the wrong way to do it?

A: 

You need to save the entity to get an id if you're using db generated identity, if you wish to create your own identities - it is fine. do what suits you, just remember what you have chosen when you test.

I usually decide on each class which is more suitable for me - either DB generated or my own.

Dani
you can unit test with a DB, and rollback the transaction in the end of the unit test. the only problem is that the identity will climb up (although no entries will be left in the db)When You unit test NH - it's maily for mapping test against DB.(plus - whoever downvote - please explain)
Dani
I just posted at possible solution at my bloghttp://techinject.blogspot.com/2009/11/how-to-unittest-entities.html
Rasmus Christensen
What I want to point out is that in my opinion the responsibility of generating id´s belongs to the repository. NHibernate is just a technical implementation detail of a repository. What if you had an in-memory repository, nhibernate would not deal with id :), but you would properly still need them. My statement about invalid Entities is from the concept of an entity in DDD, what defines an entity is that it has an identity, so someone has to generate this and for now I think this responsibility belongs to the repository
Rasmus Christensen
A: 

You need to call Session.Save on the entity before a guid is generated. You can call Session.Save to generate the entity without actually saving it to the database. This article does a pretty decent job of explaining it

lomaxx
Well the point is to not have "invalid" entities when making unittest, aka not having a DB. But I just read some bad things about why you should not use the assigned approach. So I came up with this solution:Just Create Entities through an aggregate, after all my aggregate gets injected with a repository, which I can mock/stub in my test and this way I can make sure all entities created have a valid Id.
Rasmus Christensen
A: 

Nhibernate should generate Id's for you. Id property of the entity must be protected. The best way is to use hilo

Sly
+2  A: 

In most cases you should be letting NHibernate do its job which is to handle persistence. This is important since it allows you to easily change things (we went from identity to hilo mid-project).

I would question why you care that a newly created object has an id or not? From a business point of view a persistence ID is not relevant and shouldn't be checked with via unit tests. This as mentioned is the domain of integration tests. You should be careful in how you are using an objects persistence Id throughout the rest of your application. Remember this should NOT be treated as the objects business id/key.

ShaneC
Do you think a view (say a web page view) should use persistence ID to distinguish objects? If not, how should they distinguish objects when there is no real unique business key? This becomes a concern when session.save has not been called.
Mank
I've never seen a design where when an item was added it wasn't immediately persisted and then a new dataset loaded. The reason is that any time you add an entity there are business rules on the backend (and maybe db constraints) that need to be applied.
ShaneC
A: 

Neither NHibernate nor the Application should be handling identifiers. Leave it to the database since this is the only concrete store of your data, and it is the only part of your application that knows what IDs have already been assigned and what ones are available.

Make an identity primary key column on your database table:

CREATE TABLE dbo.sample (
id int primary key identity(1,1),
...
...
...)

map your entities like this:

<id name="ID" column="id">
<generator class="identity" />
</id>

The Primary key will be generated automatically by the database when you save a new entity for the first time. IDENTITY(1,1) means "give new rows an Identity start at '1' then each subsequent row gets incremented by 1": so 1,2,3,4,5,6,7

reach4thelasers
I have let nhibernate generate primary key on save. However, there are issues identifying objects on the view side, esp. when two objects differ only my reference. How do you handle that?
Mank
Override GetHashCode() and Equals() in your objects
reach4thelasers