1

so I have an entity named Event which contains many Reports (one to many) which contains many sources (many to many).

I'm facing a problem that I just cant figure out, when I'm trying to update my event, it will try to update the report because of the cascade (which is fine) and it will try to update the report's sources on the join table because of the cascade (which is fine), but for some reason it also tries to update the Source entity, which it shouldn't update because there is no change in it.

public class Event
{
    public virtual IList<Report> Reports { get; set; }
    public virutal int Id { get; set; }
    public Event()
    {
        Reports = new List<Report>();
    }
}

public class EventMapping : ClassMap<Event>
{
    public EventMapping()
    {
        Table("EVENTS");
        Id(x => x.Id).Column("ID").GeneratedBy.Sequence("EVENT_ID_SEQ");

        HasMany(x => x.Reports).KeyCoulmn("EVENT_ID").Cascade.SaveUpdate();
    }
}

public class Report
{
    public virtual int Id { get; set; }
    public virtual int Status { get; set; }
    public virtual IList<Source> Sources { get; set; }

    public Report()
    {
        Sources = new List<Source>();
    }
}

public class ReportMapping : ClassMap<Report>
{
    public ReportMapping()
    {
        Table("REPORTS");
        Id(x => x.Id).Column("ID").GeneratedBy.Sequence("DIVUACH_ID_SEQ");
        Map(x => x.Status).Column("Status");
        HasManyToMany(x => x.Sources).Table("SOURCES_IN_REPORT").ParentKeyColumn("REPORT_ID").ChildKeyColumn("KOD_SOURCE").Cascade.All();
    }
}

public class Source
{
    public virtual int Id { get; set; }
}

public class SourceMapping : ClassMap<Source>
{
    public SourceMapping()
    {
        Table("SOURCE");
        Id(x => x.Id).Column("ID");
    }
}

here is what I do and when it fails.

var eventFromDb = _session.Get<Event>(eventId);

eventFromDb.Reports.ToList().ForEach(x => x.Status = GetStatus());

_session.Update(eventFromDb);

Any idea why?

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
Golan Kiviti
  • 3,895
  • 7
  • 38
  • 63

1 Answers1

0

Unwanted updates usually are cause be accidental changes of properties. NHibernate has automatic change tracking and updates all records when the properties do not return the exact same value that is assigned to it when loading.

See this answers:

by the way, you do not need to call update(). NHibernate updates changed entities anyway when they are in the session. Everything you load from the database (e.g. by session.get() in your case) is in the session. Just commit the transaction.

Community
  • 1
  • 1
Stefan Steinegger
  • 63,782
  • 15
  • 129
  • 193
  • 2
    Small complement: the most common phantom updates I have seen were due to the entities having non nullable properties while corresponding columns in DB were nullable and null. This causes the object properties to have different values than the ones retrieved from db. So NHibernate considers it dirty. – Frédéric Apr 05 '16 at 17:54