NHibernate add unconnected column to interceptor

I am trying to persist a mapped entity using NHibernate, but my database insert failed because there is a column in the base table that does not allow NULLs and is NOT visible in my domain object. The reason it doesn't show up is because the column in question supports a legacy application and has nothing to do with my application - so I wouldn't pollute the object with the deprecated property.

I know I can use a private field inside my class, but that still seems frustrating to me. I read that I can use the NHibernate interceptor and override the OnSave () method to add a new column right before my object is saved. This is tricky as I cannot figure out how to add an instance of Nhibernate.type.IType to the type parameters of my OnSave interceptor.

My essence looks something like this:

public class Client
{
    public virtual int Id { get; set; }
    public virtual int ParentId { get; set; }
    public virtual string Name { get; set; }
    public virtual string Phone { get; set; }
    public virtual string Email { get; set; }
    public virtual string Url { get; set; }
}

      

And my interceptor

 public class ClientInterceptor : EmptyInterceptor
{

    public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types)
    {
        if (entity is Client)
        {
            /*
              manually add the COM_HOLD column to the Client entity
            */
            List<string> pn_list = propertyNames.ToList();
            pn_list.Add("COM_HOLD");
            propertyNames = pn_list.ToArray();

            List<Object> _state = state.ToList();
            _state.Add(false);
            state = _state.ToArray();

            //somehow add an IType to types param ??

         }
         return base.OnSave(entity, id, state, propertyNames, types);
    }
}

      

Does anyone have any ideas on how to do this correctly?

+1


source to share


2 answers


I can't say for sure since I've never done this (e.g. Stefan, I also prefer to just add the private property), but can you add an array NHibernate.Type.BooleanType

to an array types

?

List<IType> typeList = types.ToList();
typeList.Add(new BooleanType());
types = typesList.ToArray();

      

EDIT

Yes, it looks like you are right; types have a constructor internal

. I did some digging and found TypeFactory

:



Applications should use static methods and constants on NHibernate.NHibernateUtil if the default IType is good enough. For example, TypeFactory would have to be used when the string should be 300 instead of 255 in length. NHibernate.String is not giving you the correct IType at this point. Use TypeFactory.GetString (300) instead and keep a local variable that contains a reference to the IType.

So it looks like what you want NHibernateUtil

:

Provides access to the entire range of NHibernate built-in types. The instances I print can be used to bind values ​​to request parameters. Also, a factory for the new Blobs and Clobs.

typeList.Add(NHibernateUtil.Boolean);

      

+1


source


Personally, I wouldn't get that difficult. I would add private property and give it the default - finished. You can also consider the default in the database, then you don't need to do anything.

private virtual bool COM_HOLD 
{ 
  get { return false; } 
  set { /* make NH happy */ } 
}

      



Before writing an interceptor for this, I would consider writing a database trigger. Because with Interceptor, you pollute your data access layer. This can make it unstable and you might have strange problems.

+1


source







All Articles