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.  [ 5 posts ] 
Author Message
 Post subject: Mapping C# bool to a Oracle NUMBER(1)
PostPosted: Wed Jun 28, 2006 4:44 am 
Beginner
Beginner

Joined: Tue Jan 17, 2006 12:55 pm
Posts: 49
This was working before for me before but seems to have stopped and I don't know why!

I have an entity which has a bool property. This is mapped to a Oracle NUMBER(1) column (trying to emulate a SQL Server bit field: 0 = false and 1 = true) as follows:

Code:
<property name="IsValid" column="IS_VALID" type="boolean" not-null="true" />


Now, this worked before but now, we I am getting errors and I can see from the NHibernate SQL that it is trying to set the field to "False" rather than 0.

How can I ensure that this works in my mapping?


I have also tried not setting the type property.


Top
 Profile  
 
 Post subject: answer?
PostPosted: Thu Jan 18, 2007 11:00 pm 
Newbie

Joined: Fri May 26, 2006 3:05 pm
Posts: 4
Did you ever get an answer for this? I am having the same problem.

Kevin


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 19, 2007 6:48 am 
Beginner
Beginner

Joined: Tue Nov 28, 2006 4:26 pm
Posts: 32
Location: Montreal, Quebec, Canada
If you have access to modify the database, change NUMBER(1) to CHAR(1) and use the included UserType as follows:

Code:
<property name="IsApproved" type="NHibernateProvider.UserType.OneZeroType, NHibernateProvider" />

Of course, you will need to change the namespace and assembly accordingly to match where you put the class.

Code:
using System;
using System.Data;
using NHibernate;
using NHibernate.SqlTypes;

namespace NHibernateProvider.UserType
{
    /// <summary>
    /// NHibernate data type to handle Oracle representation of a boolean, which is mainly <c>CHAR(1)</c>.
    /// </summary>
    /// <remarks>
    /// <p>This implementation is neceassary to avoid an exception thrown by <see cref="bool.Parse"/> since it does not know
    /// how to handle <c>1</c> or <c>0</c> and boolean values. The implementation is only required for the <see cref="NullSafeGet"/>
    /// method. Therefore, the remainder of the class delegates to the <see cref="NHibernateUtil.Boolean"/> instance.</p>
    /// <p>An alternative to using a user type to circumvent this problem is to simply use <c>NUMBER(1,0)</c> instead of <c>CHAR(1)</c>
    /// when defining a column in Oracle to represent a boolean.</p>
    /// </remarks>
    [Serializable]
    public class OneZeroType : IUserType
    {
        #region IUserType Implementation
        /// <summary>
        /// The SQL types for the columns mapped by this type.
        /// </summary>
        public SqlType[] SqlTypes
        {
            get { return new SqlType[] { NHibernateUtil.Boolean.SqlType }; }
        }
        /// <summary>
        /// The type returned by <see cref="NullSafeGet"/>.
        /// </summary>
        public Type ReturnedType
        {
            get { return typeof(bool); }
        }
        /// <summary>
        /// Compare two instances of the class mapped by this type for persistent "equality"
        /// ie. equality of persistent state.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public new bool Equals(object x, object y)
        {
            return (x == y);
        }
        /// <summary>
        /// Get a hashcode for the instance, consistent with persistence "equality"
        /// </summary>
        /// <remarks>Required for NHibernate 1.2 Beta 2.</remarks>
        public int GetHashCode(object obj)
        {
            return ((null == obj) ? GetHashCode() : obj.GetHashCode());
        }
        /// <summary>
        /// Retrieve an instance of the mapped class from a result set.
        /// </summary>
        /// <remarks>Implementors should handle possibility of null values.</remarks>
        /// <param name="rs">result set containing the data to evaluate.</param>
        /// <param name="names">column names.</param>
        /// <param name="owner">the containing entity.</param>
        /// <returns></returns>
        /// <exception cref="HibernateException">HibernateException</exception>
        /// <exception cref="System.Data.SqlClient.SqlException">SqlException</exception>
        public object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            object val = null;

            int index = rs.GetOrdinal(names[0]);
            if (!rs.IsDBNull(index))
            {
                try
                {
                    val = rs[index];
                    // This is where the magic happens.
                    val = ("1".Equals(val) ? true : ("0".Equals(val) ? false : NHibernateUtil.Boolean.Get(rs, index)));
                }
                catch (InvalidCastException ex)
                {
                    throw new ADOException(
                        "Could not cast the value in field " + names[0] + " of type " + rs[index].GetType().Name + " to the Type " + GetType().Name +
                            ".  Please check to make sure that the mapping is correct and that your DataProvider supports this Data Type.", ex);
                }
            }

            return val;
        }
        /// <summary>
        /// Write an instance of the mapped class to a prepared statement.
        /// </summary>
        /// <remarks>
        /// Implementors should handle possibility of <c>null</c> values. A multi-column type should be written
        /// to parameters starting from <paramref name="index"/>.
        /// </remarks>
        /// <param name="cmd">a IDbCommand</param>
        /// <param name="value">the object to write</param>
        /// <param name="index">command parameter index</param>
        /// <exception cref="HibernateException">HibernateException</exception>
        /// <exception cref="System.Data.SqlClient.SqlException">SqlException</exception>
        public void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            NHibernateUtil.Boolean.NullSafeSet(cmd, value, index);
        }
        /// <summary>
        /// Return a deep copy of the persistent state, stopping at entities and at collections.
        /// </summary>
        /// <param name="value">generally a collection element or entity field.</param>
        /// <returns>a copy.</returns>
        public object DeepCopy(object value)
        {
            return NHibernateUtil.Boolean.DeepCopy(value);
        }
        /// <summary>
        /// Are objects of this type mutable?
        /// </summary>
        public bool IsMutable
        {
            get { return NHibernateUtil.Boolean.IsMutable; }
        }
        #endregion IUserType Implementation
    }
}


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 25, 2007 3:37 pm 
Newbie

Joined: Tue Oct 24, 2006 9:10 am
Posts: 17
I've never used this. To represent bool I use "TrueFalse" on mapping. On my database(Oracle by the way) it changes on a Varchar2(1) with 'T' or 'F'


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 25, 2007 4:18 pm 
Beginner
Beginner

Joined: Tue Nov 28, 2006 4:26 pm
Posts: 32
Location: Montreal, Quebec, Canada
If this is the case you may only need to change the line

Code:
val = ("1".Equals(val) ? true : ("0".Equals(val) ? false : NHibernateUtil.Boolean.Get(rs, index)));

to the line

Code:
val = ("T".Equals(val) ? true : ("F".Equals(val) ? false : NHibernateUtil.Boolean.Get(rs, index)));

Alternatively, you may just check for both cases.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 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.