1
votes

I upgraded to Nhibernate 3.2.0.4000 and fluent 1.3.0.717 using Nuget. Mappings that used to work are now causing me an issue when I try to save. The data loads up fine, but when I try to change any boolean values, they are ignored. I can save text fields without any problem. In fact, I can alter a text field and boolean value in one save, and it only actually saves the text field change into the database.

First, I have an options object

public class Options
{
    public virtual long OptionsId { get; set; }

    private IList<MobileOptions> MobileGatewayList { get; set; }


    public virtual MobileOptions MobileGateway
    {
        get
        {
            if (MobileGatewayList == null)
                return null;

            return MobileGatewayList.FirstOrDefault();
        }
    }

}

And for Mobile specific options I have a class

public class MobileOptions
{
    public virtual long MobileOptionsId { get; set; }

    public virtual Options Options { get; set; }

    public virtual SharedGatewayOptions SharedGatewayOptions { get; set; }
}

SharedGatewayOptions is a class of shared options for all my subsets of options (I have 3, but am only showing mobile to keep this example concise). Specifically, where I noticed the error was in the boolean flag to enable the mobile portion of my application.

public class SharedGatewayOptions
{
    public virtual bool GatewayActivated { get; set; }
}

The mapping of the mobile options in my main options class map options looks like this

HasMany<MobileOptions>(Reveal.Member<GatewayOptions>("MobileGatewayList"))
            .KeyColumn("OptionsId")
            .Cascade.All();

I had to use a hasmany because the table containing the mobile options contains the parent Id, but the parent does not contain a column to the child table. There is no FK relationship in the database, and I could not get a HasOne to work.

Here is the mapping in the MobileOptions classmap

References<GatewayOptions>(x => x.Options, "OptionsId");

Component(x => x.SharedGatewayOptions, y =>
{
     y.Map(x => x.GatewayActivated, "ActivateGateway").Generated.Insert();
});

When I create a new options record and mobile options, this all works fine and it is set up with the defaults. But when I go to change the activation boolean (or any other boolean) there is no error and nothing is saved back to the database. However, on another child options (much like the MobileOptions) when I save a text field and a boolean field, only the text field changes.

My code for changing the bit looks like this

public void ToggleGateways(ToggleGatewaysRequest request)
{
    var options = GetOptions(new GatewayOptionsRequest() { SiteId = request.SiteId });

    options.RemoteGateway.SharedGatewayOptions.GatewayActivated = request.RemoteGatewayActivated;

    optionsRepository.Save(options);
}

This code used to work, but since the upgrade it doesn't work anymore. I traced through it and the object is being changed in memory, but then on the next request, the object is "reverted". I have stepped through the code to see if on the next request I am somehow causing the bit to flip back, and that is not the case. The database is never toughed. It's as if the newest fluent no longer knows how to map boolean -> bit on a save.

1

1 Answers

1
votes

AFAIK .Generated.Insert(); means that this property is generated when inserting and then never changed, but since you want to change it you should leave it out.

not a direct answer to your question but have you considered Joining the other table to get the desired values?

public class Options
{
    public virtual long OptionsId { get; set; }

    public virtual MobileOptions MobileGateway { get; set; }
}

// in OptionsMap
Join("MobileOptions", join =>
{
    join.Optional();
    join.KeyColumn("OptionsId");
    join.Component(x => x.SharedGatewayOptions, y =>
    {
        y.Map(x => x.GatewayActivated, "ActivateGateway");
    });
});

or an alternative class design

public class GatewayOptions
{
    public virtual bool GatewayActivated { get; set; }
}

public class MobileOptions : GatewayOptions
{
    public virtual bool Something { get; set; }
}

// in OptionsMap
RefernecesAny(x => x.Options)...;