JamminJimE
JamminJimE

Reputation: 33

Fluent NHibernate returns an IList<T> of NULL records

Ok, I have done just about everthing that I can think of. I have been all over the search engine of choice for the last 2 days and have yet to find a solution for this.

UPDATE:: I have even gone so far as to flatten the classes as seen below.

Here's what I have...

NOTE:: Class names and property names changed due to sensitivity of data!

I have an entity object named "MyData". It looks like this...

public class MyData
{
    public virtual int id { get; set;}
    public virtual int StepId { get; set;}
    public virtual Decimal ProjectedValue { get; set;}
    public virtual String Stage { get; set;}
    public virtual String CreatedBy { get; set;}
    public virtual DateTime CreatedDate { get; set;}
    public virtual int RunId { get; set;}
    public virtual Int32 DataKey { get; set;}
    public virtual DateTime ForecastDate { get; set;}
    public virtual String UnitMeasure { get; set;}
    public virtual String FixedFlag { get; set;}
    public virtual String DataSource { get; set;}
    public virtual String ResourceType { get; set;}
    public virtual String DataType { get; set;}     

              public override bool Equals(object obj)
    {
        //Not implemented
        return false;
    }

    public override int GetHashCode()
    {            
        return base.GetHashCode();
    }

    public MyData()
    {
    }
     }

Here is the code being used for the map.

        Table("MYDATA");
        CompositeId()
            .KeyProperty(mtm => mtm.RunId, "RUN_ID")
            .KeyProperty(mtm => mtm.DataKey, "CC_KEY")
            .KeyProperty(mtm => mtm.ForecastDate, "FORECAST_DATE")
            .KeyProperty(mtm => mtm.UnitMeasure, "UOM")
            .KeyProperty(mtm => mtm.FixedFlag, "FIXED_FLAG")
            .KeyProperty(mtm => mtm.DataSource, "DATA_SOURCE")
            .KeyProperty(mtm => mtm.ResourceType, "RESOURCE_TYPE")
            .KeyProperty(mtm => mtm.DataType, "DATA_TYPE")
        Map(mtm => mtm.StepId, "STEP_ID").Not.LazyLoad();
        Map(mtm => mtm.ProjectedValue, "PROJECTED_VALUE");
        Map(mtm => mtm.Stage, "STAGE").Not.LazyLoad();
        Map(audit => audit.CreatedBy, "CREATED_BY").Not.Nullable();
        Map(audit => audit.CreatedDate, "CREATED_DATE");

This class has met the requirements for mapping by NHibernate and Fluent. We are converting NHibernate to Fluent.

When I add the two restrictions to the ICriteria object and call the method to get the data back, I get (in this particular example) over 15000 records back but they are all NULL. There are no properties, no values, nothing. However, the number of returned rows are the EXACT SAME as if I run the select in the database. Here is the code that I use to select the data from the app. Please keep in mind that this exact same code works fine for other objects as we are actually reusing this method!

        ICriteria c = _session.CreateCriteria(typeof(T));

        foreach (string searchField in searchCriteria.Keys)
        {
            c.Add(Restrictions.Eq(searchField, searchCriteria[searchField]));
        }

        IList<T> l = c.List<T>();

When I step through the code, the collection "l" has the rows, but they are all NULL objects. They are, however, of Type.

A couple of final closing thoughts...

  1. Other objects in the code base use this same ICriteria object and return data fine.
  2. The NHibernate mapping of this object matches the Fluent mapping identically.
  3. This application containing this code runs quite well, especially for the amount of
    data being consumed and created.
  4. This database table in Oracle has NO PK. (I didn't design it, I just inherited it!)

HELP!! I am completely confused by this return and can't find anything wrong.

Upvotes: 1

Views: 1596

Answers (1)

JamminJimE
JamminJimE

Reputation: 33

I finally figured it out after 3 days of thinking that I'd done something wrong.

Basically, the problem existed in the mapping of the CompositeId object. The objects listed above were edited in an attempt to remove the CompositeId object all together. Instead of ID being a simple INT, it was an object containing 8 other properties.

Well, the CC_KEY column (DataKey property) for the specified RunId was set to NULL in the database. When I tried to query the object and create a compositeKey, the null object was causing the failure on EACH row of the incoming data. This prevented FluentNHibernate from creating the CompositeId object. No Id, no object! This allowed the system to return me the correct number of results but, when attempting to create each object with a null CompositeKey.KeyColumn value, it failed.

Long story short, if you're creating a compositeId for a mapped object, make SURE that all of your data exists and there are no NULL values!

Upvotes: 2

Related Questions