I work with a database that depends heavily on identity columns. However as we have now moved all applications over to NHibernate I wanted to look into using HiLo as seems to be recommended with NHibernate. Are there any strategies to do this, or any common problems to watch out for?
相关问题
- Using StoreGeneratedPattern.Identity with database
-
NHibernate Query
with detached criteria… - Python pickling keep object identity
- R time series data, daily only working days
- Fluent NHibernate automap PostGIS geometry type
相关文章
- Given a list and a bitmask, how do I return the va
- Fluent NHibernate — Saving Entity with Composite K
- Is this the right way of using ThenFetch() to load
- Can Persistence Ignorance Scale?
- SQL identity (1,1) starting at 0
- rxjs timeout to first value
- How to find if a referenced object can be deleted?
- NHibernate SQL query slow
You need to setup the table used by NH to create HiLo values correctly. Let Schema Creator create the table according to your mapping definitions, set the values according to the current state of the ids in your database.
I believe (you need to verify this) that values generated by hilo are calculated by:
While the high-value is stored in the database, max_low defined in the mapping file and low-value calculated at runtime.
NHibernate also needs its own connection and transaction to determine and increment the high value. Therefore it does not work if the connection is provided by the application.
You can still use
seqhilo
, NH uses a database sequence to create next high-values and does not need a separate connection to do so. This is only available on databases which support sequences, like Oracle.Correction:
Meanwhile, I had to implement it myself (before, it was just theory :-). So I come back to share the details.
The formula is:
next_hi
is the field in the database you need to update.highest_id
is the highest ID found in your database.maxLow
is the value you specified in the mapping file. No Idea why it is incremented by one. The division is an integer devision which truncates the decimal places.Here's a script (MS SQL) that will fill HiLo(Name,Value) table with all next high numbers for all tables in current database:
If this is a question about migrating an existing application to hilos which previously used auto ids, and has old data in it which needs to be migrated... then this would be my best bet (not tried it though! - comments welcome!) :
If course this only addresses issues with the identity column, not anything else in your schema that might need to change if you are moving an app to NHibernate.
Here is a sample from a recent migration from the increment generator to the MultipleHiLoPerTableGenerator (e.g. a single table is used to store high values for every Entities).
My application is using Hibernate 3 + mapping files (.hbm.xml). My database is MySQL (innoDB + auto increment pk).
Step 1 : replace your generator settings in your .hbm files. Replace :
By
Step 2 : create a new table to store the high values
Step 3 : populate the initial high values according to existing data using the following piece of SQL. I assume here that the same
max_lo
value is used for every table.I wrote a script (based of Stephans answer) for fixing hilo values (on sql server) - it assumes that you have a hilo table like
And your table's identity columns are all called ID. Init the Entity table with the table names you want to generate the hilo values for. Running the script will generate a series of update statements like this one:
Here it is