NHibernate HiLo ID Generator. Generating an ID before saving

后端 未结 1 1329
挽巷
挽巷 2020-12-17 06:42

I\'m trying to use \'adonet.batch_size\' property in NHibernate. Now, I\'m creating entities across multiple sessions at a large rate (hence batch inserting). So what I\'m

相关标签:
1条回答
  • 2020-12-17 07:15

    I find it odd that you need many sessions to do a single job. Normally a single session is enough to do all work.

    That said, the Hilo generator sets the id property on the entity when calling nhSession.Save(object) without necessarily requiring a round-trip to the database and a nhSession.Flush() will flush the inserts to the database

    UPDATE ===========================================================================

    This is a method i used on a specific case that made pure-sql inserts while maintaining NHibernate compatibility.

    //this will get the value and update the hi-lo value repository in the datastore
    public static void GenerateIdentifier(object target)
    {
          var targetType = target.GetType();
          var classMapping = NHibernateSessionManager.Instance.Configuration.GetClassMapping(targetType);
          var impl = NHibernateSessionManager.Instance.GetSession().GetSessionImplementation();
    
          var newId = classMapping.Identifier.CreateIdentifierGenerator(impl.Factory.Dialect, classMapping.Table.Catalog, classMapping.Table.Schema,
                                                                  classMapping.RootClazz).Generate(impl, target);
          classMapping.IdentifierProperty.GetSetter(targetType).Set(target, newId);
    }
    

    So, this method takes your newly constructed entity like

    var myEnt = new MyEnt(); //has default identifier
    GenerateIdentifier(myEnt); //now has identifier injected based on nhibernate's mapping
    

    note that this call does not place the entity in any kind of nhibernate managed space. So you still have to make a place to place your objects and make the save on each one. Also note that i used this one with pure sql inserts and unless you specify generator="assigned" (which will then require some custom hi-lo generator) in your entity mapping nhibernate may require a different mechanism to persist it.

    All in all, what you want is to generate an Id for an object that will be persisted at some time in the future. This brings up some problems such as handling non-existent entries due to rollbacks and failed commits. Additionally imo nhibernate is not the tool for this particular job, you don't need nhibernate to do your bulk insert unless there is some complex entity logic that is too costly (in dev time) to implement on your own.

    Also note that you are implying that you need transient detached entities which however cannot be used unless you call .nhSes.Save(obj) on the first session and flush its contents so the 2nd session when it calls Load on the transient object there will be an existing row in the database which contradicts what you want to achieve.

    Imo don't be afraid of storming the database, just optimise the procedure top-to-bottom to be able to handle the volume. Using nhibernate just to do an insert seems counter-productive when you can achieve the same result with 4 times the performance using ado.net or even an isqlquery wrapped-query (and use the method i provided above)

    0 讨论(0)
提交回复
热议问题