Skip to content

NH-1806 - ISession.Replicate() should attempt an identity insert #861

Open
@nhibernate-bot

Description

@nhibernate-bot

Sukh created an issue — 29th May 2009, 8:38:10:

See HHH-2716 for the Hibernate issue.

When my application first runs, I need to do an initial population of the database. For this, I have to ensure that the identifier column is the exact value I need for each persistent object. To do this, I guess I should use Replicate() to force a particular identity value to be inserted. Unfortunately, Replicate() seems to act the same as Save when the ID column is an identity - i.e. it doesn't send the ID column value to the database.

For example, I have a persistent object (BusinessRegion - ID 1, Name "Europe"). When using replicate, I expect the following query:

INSERT INTO BusinessRegion
(ID, Name)
VALUES (1, 'Europe')

Instead, I get:

INSERT INTO BusinessRegion
(Name)
VALUES ('Europe')

Before running this query, I can send "SET IDENTITYINSERT ___ ON" to SQL, which should allow me to insert the identity column.


Fabio Maulo added a comment — 29th May 2009, 20:32:02:

AFAIK Replicate can't work with PostInsertIdentifier generators as identity, triggers and so on.


Sukh added a comment — 30th May 2009, 3:15:32:

This should work with identity columns, for SQL Server at least (see SET IDENTITY_INSERT ON). I will see if I can come up with a patch for NH 2.1.


Fabio Maulo added a comment — 30th May 2009, 16:52:00:

There is a more easy solution.
Don't use identity and identity-style generators!!


Sukh added a comment — 1st June 2009, 2:37:33:

It's a tad bit too late for that. Not quite in the mood to change 200-odd tables/classes/mappings for that ;)


Sukh added a comment — 1st June 2009, 4:07:42:

This patch forces the key to be passed to the database when the Replicate() method is used. This matches what the documentation says should happen: "Persist the state of the given detached instance, reusing the current identifier value. "

Obviously this will fail using an identity column, but with SQL Server at least you can use "SET IDENTITY_INSERT ON" to override the default identity generation behaviour.


Fabio Maulo added a comment — 1st June 2009, 15:35:07:

mmmm... no tests, nothing about "SET IDENTITY_INSERT ON", nothing about the others PostInsertIdentifier, nothing about applicability of the same solution with others RDBMS....

Try to analyze it a bit more deeper.
For example:

  • The dialect should have: public virtual bool SupportsIdentityOnReplicate
  • The dialect should have: public virtual string IdentityOverrideEnable
    and so on...

Sukh added a comment — 8th June 2009, 10:24:38:

I've added a test that demonstrates the failure to insert an identity column on replicate.

I've added the approriate properties and methods to dialect, and overridden them on MsSql2005Dialect (see SupportsIdentityInsertOnReplicate, GetStartIdentityInsertString(string tableName) and GetEndIdentityInsertString(string tableName) ).

I've also modified DefaultReplicateEventListener to always generate the key when replicating (I think to match the documentation, this should actually fail for dialects that don't support identity insertion??)

Now, all I need to do is call GetStartIdentityInsertString() and GetEndIdentityInsertString() before any identity inserts when replicating only. Any tips as to how I should do this? :)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions