i have read in more then one place that using NHibernate’s Identifier as
Primary Key is considered a bad practice because the id are generated at the server side
and hence we need a reply from the server about the generated ids.
(i think that i have also seen a post by Ayende that says that ms-sql server may have problems
generating identifier and this can cause primary key violations)
now, let’s say i have a very simple domain-model: blogs and post. where every blog can have
many posts and each post belongs to EXACTLY one blog (one to many relationship)
but WE ONLY SAVE THE Post -> Blog relationship and not the Blog -> Posts
now suppose i use NHibernate WITH Idenitifer Id Generation such that i don’t use cascading so i have in my c# code something like this:
SaveBlogInTransaction(blog1);
SavePostsInTransaction(blog1posts);
now, my question is this: if the insertion can be done only in one place in my code
(there are no concurrency issues), is it guaranteed that the posts’ connection to their blog in the db will be valid?
i mean let’s look at the Posts’ table schema:
PostId, PostName, PostType, BlogId
is it guaranteed that the BlogId will be valid?
note: each method works as a transaction and at the end it does a commit to the db
The posts will have the correct Blog ID even in your re-phrased question. NHibernate will insert the Blog row in the database as soon as Save is called and will retrieve the generated identity value using SCOPE_IDENTITY at that time. This ID value will be stored in the Blog object and be available for any posts created later.
This is why people say that identity-based IDs are not a good choice – NHibernate must execute the SQL to insert the row immediately so that the correct identity value can be obtained. If a different identity generator is used NHibernate can avoid executing the SQL insert statements until the transaction is committed since the database does not need to be contacted to determine the value of the object’s ID.