What's the recommended approach when an Aggregate Root changes?

61 views
Skip to first unread message

Stijn Volders (ONE75)

unread,
Apr 23, 2012, 4:26:25 PM4/23/12
to rav...@googlegroups.com
Hi,

Let's say I want to add a property to my "BacklogItem" class:

public Priority Priority {get;set;}

with a default value "Priority.High" (as always...)

When dealing with a RDMS, I would create the column with a default value and i'm ready to go. How do I update the documents in my database with RavenDB? I couldn't find info on the site about that, but maybe I'm looking with the wrong keywords (document change or migration yielded other results)

Thanks

Stijn

Itamar Syn-Hershko

unread,
Apr 23, 2012, 4:27:45 PM4/23/12
to rav...@googlegroups.com
You just add the property and set the default value in the object ctor, like you will normally do

It will just work from there.

Stijn Volders (ONE75)

unread,
Apr 23, 2012, 6:15:45 PM4/23/12
to rav...@googlegroups.com
thanks. That would work I guess.

Normally, I would add a parameter "priority" to the ctor and assign the value of the parameter to my property, so I don't need the "default" value in my code. Only the current documents in the database violate my invariant.

I just did some tests. Apparently the values of my ctor parameters are defaulted when the document is deserialized. I've tried it with an enum and the first value of my enum was used if there is nothing in my document (not a null value, the property itself is also not in the document)

that's kind of tricky behavior, no?

Matt Warren

unread,
Apr 23, 2012, 7:13:38 PM4/23/12
to rav...@googlegroups.com
Well if the field doesn't exist in the doc/json, there's no value for RavenDB to deserialize, so it's just left as the default/existing value.

Have a read of this blog post, it give you so more info about doing migrations.

Matt Warren

unread,
Apr 23, 2012, 7:16:00 PM4/23/12
to rav...@googlegroups.com
If you want to change the actual data in the doc store, rather than what is deserialised, you can use patching

See http://ravendb.net/docs/client-api/set-based-operations and http://ravendb.net/docs/client-api/partial-document-updates


On Monday, 23 April 2012 23:15:45 UTC+1, Stijn Volders (ONE75) wrote:

Stijn Volders (ONE75)

unread,
Apr 24, 2012, 3:00:33 AM4/24/12
to rav...@googlegroups.com
Thanks Matt! Looks like everything I need to know is in these posts.

Ryan Heath

unread,
Apr 24, 2012, 5:27:34 AM4/24/12
to rav...@googlegroups.com
What you see here, is that c'tors are not invoked during deserializing.
Your enum property was just initialized with value 0, which is the
value or your first enum value.

// Ryan

On Tue, Apr 24, 2012 at 12:15 AM, Stijn Volders (ONE75)

Oren Eini (Ayende Rahien)

unread,
Apr 24, 2012, 5:28:29 AM4/24/12
to rav...@googlegroups.com
Actually, the ctor IS invoked

Ryan Heath

unread,
Apr 24, 2012, 5:30:51 AM4/24/12
to rav...@googlegroups.com
Do you (Raven) call it yourself? The .net infrastructure does not.

// Ryan

Oren Eini (Ayende Rahien)

unread,
Apr 24, 2012, 5:34:02 AM4/24/12
to rav...@googlegroups.com
Yes, it does.
Unless you call UnsafeCreateObject ( or something like that)

Matt Warren

unread,
Apr 24, 2012, 5:40:43 AM4/24/12
to rav...@googlegroups.com
I ran into this the other week, if you use the code below, it won't call the ctor (I think WCF deserialization uses this)

   FormatterServices.GetUninitializedObject(typeof(MyClass)

Ryan Heath

unread,
Apr 24, 2012, 5:44:11 AM4/24/12
to rav...@googlegroups.com
Hmm,

This test fails:

[Serializable]
public class Class1
{
[NonSerialized]
public int nonSerialized;

public Class1()
{
nonSerialized = 42;
}
}

[TestFixture]
public class Test
{
[Test]
public void TestCtor()
{
var myObject = new Class1();
var formatter = new BinaryFormatter();

var mem = new MemoryStream();
formatter.Serialize(mem, myObject);
mem.Position = 0;
var newObject = (Class1)formatter.Deserialize(mem);

Assert.That(newObject.nonSerialized, Is.EqualTo(42));
}
}

Which serialization do you use?

// Ryan

On Tue, Apr 24, 2012 at 11:34 AM, Oren Eini (Ayende Rahien)

Oren Eini (Ayende Rahien)

unread,
Apr 24, 2012, 5:54:15 AM4/24/12
to rav...@googlegroups.com
That is because you are using binary serialization. Json serialization and just about anything else calls the ctor.

Ryan Heath

unread,
Apr 24, 2012, 6:17:54 AM4/24/12
to rav...@googlegroups.com
Ah, learning something new each day :)
I was pretty sure serialization was not calling the ctor, but I did
not think about the other serialization types.

It feels troublesome they don't behave alike ...

// Ryan

On Tue, Apr 24, 2012 at 11:54 AM, Oren Eini (Ayende Rahien)

Matt Warren

unread,
Apr 24, 2012, 6:26:23 AM4/24/12
to rav...@googlegroups.com
It is wierd, but I wonder if the expectation around binary serialisation is different, i.e. you wouldn't expect it to call the ctor because it's in effect making a binary clone of your object?

The others are more explicit, from what I remember the XMLSerializer demands that you have a public parameterless ctor, so there's an expectation that it will call it.
Reply all
Reply to author
Forward
0 new messages