4

I'm trying to use Fluent NHibernate mapping to serialize / deserialize data.

Starting from a "root" entity, I use the mapping to build a graph with all the entities linked to that entity. Then I serialize this set of entities.

I've got this mapping (only relevant parts) :

[Serializable]
public class Foo
{
    public virtual IList<Bar> Bars { get; set;}
    public virtual IList<System.Guid> Guids { get; set; }
}

[Serializable]
public class Bar
{
    public virtual Foo Foo { get; set; }
}

public class BarMap : ClassMap<Bar>
{
    References(x => x.Foo, "idFoo").Not.Nullable();
}

public class FooMap : ClassMap<Foo>
{
    HasMany(x => x.Bars).KeyColumn("idFoo");
    HasMany(x => x.Guids).Table("guids").KeyColumn("idFoo").Element("guid").AsBag().Not.LazyLoad();
}

Everything works correctly for Foo and Bar serialization and deserialization. But when trying to persist the deserialized data back in the DB, the Guids list isn't persisted, although its data is found in the Foo object.

I googled around for some time, but didn't find anything useful. I tried with Inverse too, to no avail. I also tried to Cascade.SaveUpdate(), which also didn't work.

Is it because it uses an extra table to store values as Elements ? That's the only specificity about this list I can think of.

What am I missing that prevents this restoration from working ?

Any idea welcome. Thanks.

EDIT:

The Guids list is serialized and deserialized correctly. The only thing that isn't done is the DB insertion of the guids list, but it's present in the deserialized data.

EDIT 2:

The weird part is that another piece of code elsewhere in the project does the same, this time successfully. So maybe is it a obscure NHibernate configuration parameter being different on both sides, but the mainNH.xml.config is the same file each time.

xlecoustillier
  • 16,183
  • 14
  • 60
  • 85
  • There seems to be some confusion here. .Net serialization has nothing to do with the (Fluent) NHibernate mappings. Is the deserialization happening correctly? That is, can you see the list of guids in the object after deserialization? – Oskar Berggren Feb 19 '13 at 15:15
  • what datatype does the column guid have? it is generated using SchemaExport? – Firo Feb 20 '13 at 07:14
  • In DB, Guids are `UNIQUEIDENTIFIER`. Yes, it is generated using SchemaExport. – xlecoustillier Feb 20 '13 at 09:07
  • One way I debug such cases is to look at the actual sql fired with each permutation. I would have hoped an inverse mapping would have done the trick, well, let me try this out in my box. – Srikanth Venugopalan Feb 26 '13 at 01:20
  • @SrikanthVenugopalan I looked at the generated SQL, of course. On the side that works (EDIT2), the `Foo` class gets inserted, and then the guids are just after. But the guids insertion just doesn't occur on the part that tricks me. No error or anything. – xlecoustillier Feb 26 '13 at 08:23
  • Have you tried adding a `.Cascade.AllDeleteOrphan()` to the end of the `HasMany` mapping? (Not answered as a question 'cos I've not tried to replicate your problem). – Andrew Skirrow Feb 27 '13 at 07:41
  • Yes I tried, didn't work. – xlecoustillier Feb 27 '13 at 08:03

4 Answers4

1

It's likely your Save/Update isn't cascading to child collection.

Change your mapping to

  HasMany(x => x.Guids).Cascade.SaveUpdate().Table("guids").KeyColumn("idFoo").Element("guid").AsBag().Not.LazyLoad();
Herman Schoenfeld
  • 8,464
  • 4
  • 38
  • 49
  • No, the values still don't get persisted back. I just retried, but in fact I had already tried this. Sorry, I should have mentioned it. – xlecoustillier Feb 25 '13 at 10:53
1

Try adding an Inverse(false) into your HasMany mapping.

Herman Schoenfeld
  • 8,464
  • 4
  • 38
  • 49
  • I can't specify any argument for `Inverse()` method. Anyway, I tried both with and without `Inverse()`, with the same result. – xlecoustillier Feb 25 '13 at 13:16
1

Try flushing your session before you Save, and make sure you Save (not SaveOrUpdate).

Herman Schoenfeld
  • 8,464
  • 4
  • 38
  • 49
1

Try

Session.Merge(bar);
Session.Merge(bar.Foo);
Session.SaveUpdate(bar);
Herman Schoenfeld
  • 8,464
  • 4
  • 38
  • 49
  • I can't do that, as I don't know the entity type at runtime. The given example is only a really simplified mapping with only two classes, but in fact there are dozens. Only a few of them causes this problem (each time the mapping is a extra table with `Element` command), but I can't just deal with them individually, because I have to guarantee that future classes will be processed correctly, no matter their mapping configuration. – xlecoustillier Feb 26 '13 at 09:15
  • I still haven't found a solution to my problem, so I ended building a walkaround. I still award you the bounty for the effort. Thanks. – xlecoustillier Mar 01 '13 at 08:35