-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Trim string type
PostPosted: Tue Dec 18, 2007 7:33 am 
Newbie

Joined: Tue Dec 18, 2007 7:22 am
Posts: 4
Hi,

I'm having unwanted session flush effect because i'm trimming the values fetched from the database. I'm using a custom accessor and custom value types e.g. to get objects from string values based on the configuration. Since the end-users sometimes tend to input unwanted whitespace to these values, I found that the most effective way to match the strings is to trim them in my value type base constructor.

I created a custom user type TrimStringType that uses trimmed strings to compare persistent state. The problem with this type is that i'm missing the nice feature to specify the string length. And the mappings get pretty ugly, since I have to specify the full type name for the type attribute.

If you you have any suggestions how I should handle this, please help. Is there any way to get my TrimStringType to behave like the StringType (e.g type='TrimString(20)').

-- Chuck


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 21, 2007 11:47 am 
Expert
Expert

Joined: Fri Oct 28, 2005 5:38 pm
Posts: 390
Location: Cedarburg, WI
Chuck, I don't know if this answers your question about specifying lengths, but we created this custom user type, because for outdated technical reasons we are forced to use CHARs instead of VARCHARs:
Code:
using System;
using System.Data;

using NH = NHibernate;

namespace OurCompany.Framework.DataAccess.Providers.NHibernate.UserTypes
{
    /// <summary>
    /// An <see cref="NH.UserTypes.IUserType"/> that reads a <c>null</c> value from an <c>string</c>
    /// column in the database as a <see cref="String.Empty">String.Empty</see>
    /// and writes a <see cref="String.Empty">String.Empty</see> to the database
    /// as <c>null</c>.  Trailing blanks are trimmed when coming from and going to
    /// the database, and are ignored in comparison for equality.
    /// </summary>
    /// <remarks>
    /// This is intended to help with Windows Forms DataBinding and the problems associated
    /// with binding a null value.  See <a href="http://jira.nhibernate.org/browse/NH-279">
    /// NH-279</a> for the origin of this code.
    /// </remarks>
    public class EmptyTrimmedStringType : NH.UserTypes.IUserType
    {
        private NH.Type.StringType _stringType;

        public EmptyTrimmedStringType()
        {
            this._stringType = (NH.Type.StringType) NH.NHibernateUtil.String;
        }

        #region IUserType Members

        bool NH.UserTypes.IUserType.Equals(object x, object y)
        {
            if (object.ReferenceEquals(x, y))
            {
                return true;
            }

            return object.Equals(
                (x == null || x == DBNull.Value ? String.Empty : x.ToString().TrimEnd()),
                (y == null || y == DBNull.Value ? String.Empty : y.ToString().TrimEnd()));
        }

        public object Assemble(object cached, object owner)
        {
            return cached;
        }

        public object Disassemble(object value)
        {
            return value;
        }

        public object Replace(object original, object target, object owner)
        {
            return original;
        }

        public NH.SqlTypes.SqlType[] SqlTypes
        {
            get
            {
                return new NH::SqlTypes.SqlType[] {this._stringType.SqlType};
            }
        }

        public System.Data.DbType[] DbTypes
        {
            get
            {
                return new System.Data.DbType[] {this._stringType.SqlType.DbType};
            }
        }

        public object DeepCopy(object value)
        {
            return value;
        }

        public void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            if (value == null ||
                value == DBNull.Value ||
                value.ToString().TrimEnd().Equals(string.Empty))
            {
                ((IDbDataParameter) cmd.Parameters[index]).Value = DBNull.Value;
            }
            else
            {
                this._stringType.Set(cmd, value.ToString().TrimEnd(), index);
            }
        }

        public System.Type ReturnedType
        {
            get
            {
                return typeof(string);
            }
        }

        public object NullSafeGet(System.Data.IDataReader rs, string[] names, object owner)
        {
            int index = rs.GetOrdinal(names[0]);

            if (rs.IsDBNull(index))
            {
                return string.Empty;
            }
            else
            {
                return rs[index].ToString().TrimEnd();
            }
        }

        public bool IsMutable
        {
            get
            {
                return false;
            }
        }

        public int GetHashCode(object obj)
        {
            return obj.GetHashCode();
        }

        #endregion
    }
}


We then use it in mappings like this:
Code:
<property name="Description" column="description" type="OurCompany.Framework.DataAccess.Providers.NHibernate.UserTypes.EmptyTrimmedStringType, OurCompany.Framework.DataAccess" length="50" />


Note that this user type won't work on ID columns -- NHibernate gets upset if you trim the value. Apparently somewhere it keeps a raw copy of the column value instead of calling NullSafeGet(), and then some direct comparison (rather than calling Equals()) fails. This sounds like a bug to me ...


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.