0

I'm using FluentNHibernate to try and update a class with a very simple mapping (below). Language does NOT have to be selected. When I do an Insert and I've set the Language property, everything works as expected. If I then try and do an update, setting ONLY the reference property, no update statement is issued. If I update one of the non reference properties AND the Language, the update statement is issued.

I'm using NH v.3.3.1.4000 and FluentNH v.1.3.0.733.

public class OrderItem
{
    public OrderItem()
    {
        OrderDate = DateTime.Now;
        OrderStatus = Models.OrderStatus.Pending;
    }

    public virtual int OrderId { get; set; }
    public virtual Language Language { get; set; }
    public virtual DateTime OrderDate { get; set; }
    public virtual OrderStatus OrderStatus { get; set; }
}


public class OrderItemMap : ClassMap<OrderItem>
{
    public OrderItemMap()
    {
        Table("tblOrder");

        Id(x => x.OrderId);

        Map(x => x.OrderDate);
        Map(x => x.OrderStatus).CustomType(typeof(Int32));


        References(x => x.Language, "LanguageID").Cascade.None();

    }
}

public class LanguageMap : ClassMap<Language>
{
    public LanguageMap()
    {
        Id(x => x.Id);
        Map(x => x.Name);
        Map(x => x.LanguageCode);
    }
}

public class Language
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string LanguageCode { get; set; }
}

//code to update the object. uncommenting code setting the quantity forces the update, but setting only the Language does not.

        NHibernateRepository<Language> languagedb = new NHibernateRepository<Language>(SessionFactory);
        NHibernateRepository<UserDetail> userdb = new NHibernateRepository<UserDetail>(SessionFactory);

        var newItem = itemdb.All().Where(x => x.OrderId == 16).First();

        newItem.Language = languagedb.All().Where(x => x.Id == 1).First();
        //newItem.Quantity = 200;

        itemdb.Update(newItem);
Steven
  • 860
  • 6
  • 24

2 Answers2

1

Try to use Cascade.SaveUpdate() on your Language reference, instead of Cascade.None().

Read more about cascade options on Ayende's post, or on official NHibernate documentation.

Miroslav Popovic
  • 12,100
  • 2
  • 35
  • 47
  • I had tried that and just tried again after you've said. Still nothing. – Steven Jul 22 '12 at 22:26
  • @Steven Sorry, I just realized this won't help in your case. Could you post your `Language` class and mapping? Also, what does your code for updating `Language` property and saving `OrderItem` looks like? – Miroslav Popovic Jul 22 '12 at 22:40
  • updated. if I set the Quantity, everything gets updated as expected. – Steven Jul 22 '12 at 23:26
  • @Steven Just a stupid question... When you are changing the `Language` property, are you trying to set it to another `Language`, or the one that was already set? I.e. in your example above, did `OrderItem.Language` already contained `Language` with Id = 1? What happens when you set the property to `null`? – Miroslav Popovic Jul 23 '12 at 10:40
  • fair question. The orderitem's language was NULL now I'm trying to set it and update. No go. – Steven Jul 23 '12 at 12:28
  • @Steven strange indeed... It's like NHibernate session is ignoring your Language property when saving state for the object, or when checking if object is dirty. Does the same thing happen when Language property is not null - i.e. when you are changing Language value from one instance to another? – Miroslav Popovic Jul 23 '12 at 12:49
  • ok, it works if I do a BeginTransaction OR if I call Flush after even though I have flush mode set to Always. I swear I tried flush last nite but it didn't work. must have changed something... – Steven Jul 23 '12 at 14:49
  • You should always use transactions... at least when doing writes: http://stackoverflow.com/questions/3304347/should-i-always-use-transactions-in-nhibernate-even-for-simple-reads-and-writes – Miroslav Popovic Jul 23 '12 at 14:53
  • this I know, I was just playing with a unit test. didn't think I'd have too. – Steven Jul 23 '12 at 14:55
0

Have you used same session for both repositories? Have you used transaction for your sessions? If so, try to do session.Commit() or at least session.Flush(). More details here at SO

Community
  • 1
  • 1
Akim
  • 8,469
  • 2
  • 31
  • 49
  • I've tried session.Flush() but not commit as I'm not using transactions. – Steven Jul 23 '12 at 14:36
  • transaction works. And now if I call Flush explicitly it works, though I had set flush mode to Always. I swear it didn't work last nite!! – Steven Jul 23 '12 at 14:49
  • Great! Transaction, deferred operations and cache are connected at nHibernate – Akim Jul 23 '12 at 14:53
  • it's recommended to work with transaction, and I do so. Read more [at nhprof: Use Of Implicit Transactions Is Discouraged](http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions) – Akim Jul 23 '12 at 15:04
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/14290/discussion-between-akim-and-steven) – Akim Jul 23 '12 at 15:58