Do I need to store Raven's ID in my instance?

98 views
Skip to first unread message

Ewout

unread,
Aug 26, 2011, 8:01:02 AM8/26/11
to ravendb
I am using RavenDb in such a way that I do not really care about the
id's Raven assigns to the documents. It is entirely possible to
retrieve documents by criteria, store new documents, update them
etcetera. However, when I try to get metadata for a previously stored
document, I get an exception telling me that Raven cannot find the
document's key. Do I really need to have an extra Id property to
store raven's ID (or equivalently: tell Raven to use my own ID
properties on the documents)?

Example testcase:

using (var sess = store.OpenSession())
{
var a1 = new RavenA { SomeProp = "findme" };

sess.Store(a1);
sess.Advanced.GetMetadataFor(a1)["METAPROP"] =
"metadata";
sess.SaveChanges();
}

using (var sess2 = store.OpenSession())
{
var a1 = sess2.Query<RavenA>().Where(a =>
a.SomeProp == "findme");

Assert.AreEqual("metadata",
sess2.Advanced.GetMetadataFor(a1)["METAPROP"]);
}

Itamar Syn-Hershko

unread,
Aug 26, 2011, 8:17:38 AM8/26/11
to rav...@googlegroups.com
You can't GetMetadataFor an entity that hasn't been stored yet. This will work:

 using (var sess = store.OpenSession())
               {
                   var a1 = new RavenA { SomeProp = "findme" };

                   sess.Store(a1);
                   sess.SaveChanges();

Ewout

unread,
Aug 26, 2011, 8:41:19 AM8/26/11
to ravendb
Hi Itamar, thanks for your answer, but no, this does not fix it!

Both my and your version will put the new object in the storage. After
the first using() block, I _do_ have my data and metadata in raven's
database. This part works.

Now, in the second using(), Raven will perfectly find the stored
object, but only when I try to get the metadata I get an exception:

System.InvalidOperationException: Could not find the document key for
SomeProp:findme

It looks like Raven really wants to have a dedicated document key.
Mind you, in a production system ofcourse my object would have some
business key that I could use, but why would the given case not work?


Regards,

Ewout


On 26 aug, 14:17, Itamar Syn-Hershko <ita...@hibernatingrhinos.com>
wrote:

Itamar Syn-Hershko

unread,
Aug 26, 2011, 8:54:20 AM8/26/11
to rav...@googlegroups.com
Raven actually HAS a document key for every document it persists, which is automatically generated unless explicitly specified. An Id property in your class definition is just an alias for @metadata.@id

The problem was with you trying to load metadata for the wrong entity (a collection of RavenA). A simple use of FirstOrDefault solved this:

        [Fact]
        public void CanWorkWithMetadata()
        {
            using (var store = NewDocumentStore())
            {
                using (var sess = store.OpenSession())
                {
                    var a1 = new RavenA {SomeProp = "findme"};

                    sess.Store(a1);
                    sess.SaveChanges();

                    sess.Advanced.GetMetadataFor(a1)["METAPROP"] = "metadata";
                    sess.SaveChanges();
                }

                using (var sess2 = store.OpenSession())
                {
                    var a1 = sess2.Query<RavenA>().Where(a => a.SomeProp == "findme").FirstOrDefault();

                    Assert.Equal("metadata", sess2.Advanced.GetMetadataFor(a1)["METAPROP"]);

Itamar Syn-Hershko

unread,
Aug 26, 2011, 8:57:45 AM8/26/11
to rav...@googlegroups.com
And to correct my initial response - since metadata is managed by the UoW, you can actually can work with it also before persisting to the store:

        [Fact]
        public void CanWorkWithMetadata()
        {
            using (var store = NewDocumentStore())
            {
                using (var sess = store.OpenSession())
                {
                    var a1 = new RavenA {SomeProp = "findme"};
                    sess.Store(a1);

Ewout

unread,
Aug 26, 2011, 9:17:19 AM8/26/11
to ravendb
Thanks for the speedy answer! Never noticed (because of 'var' and
GetMetadata() accepting object) that my test was wrong. The actual
problem in my code (which I hoped was simulated using this test) _did_
use SingleOrDefault() however. Anyway, this test proves it can be
done, I'll just have to find out why my actual code does not work.
Sigh!

Thanks again!



On 26 aug, 14:57, Itamar Syn-Hershko <ita...@hibernatingrhinos.com>
wrote:

Itamar Syn-Hershko

unread,
Aug 26, 2011, 9:21:08 AM8/26/11
to rav...@googlegroups.com
Yep, np
Reply all
Reply to author
Forward
0 new messages