We are mapping the primary key of an object like this:
Id(x => x.Id, "ID").GeneratedBy.Native("SEQUENCENAME");
We have business logic depending on certain ids to exist (legacy, not easily changed). New objects should get generated ids from an Oracle sequence, but there are always rows with known ids.
We’re using SQLite for unit testing and I need to persist new objects to the in-memory database with these known ids. This will not work with any of the following methods:
session.Replicate(objectWithKnownId, <any replication mode>);
session.Merge(objectWithKnownId)
According to nHibernate documentation, the Replicate method seems to be what I’m looking for.
Persist all reachable transient
objects, reusing the current
identifier values.
When using it with SQLite, however, I will only get generated ids. Can anyone think of a good way of solving this?
After looking into this problem and reading the respons from AlexCuse (+1 to his answer), I deemed it was not possible to use the native id generator in this case. I both needed unit tests to work when saving rows with known ids in test setups and tests inserting with autogenerated ids.
One option was to have some sort of check in the fluent mapping that would use
GeneratedBy.Native("SEQUENCENAME")in production code andGeneratedBy.Assignedin tests, but I didn’t like the idea of having differences related to NHibernate mappings between unit tests and production.What I opted for in the end was to handle this in the repository. I have an
Addmethod in the relevant repository and this will handle assigning a generated id from a sequence if the id isn’t already set, something like this:In unit tests I will insert a mock sequence generator in the repository. You could argue that this is similar to the approach of having different mappings for unit tests and production code, but I think this approach makes the difference a bit more isolated. The most important reason, though, is that it allows me to use both assigned and automatically generated ids also in unit tests.