Creating a document if it doesn't exist in a Patch

70 views
Skip to first unread message

Jason Aminto

unread,
Jun 26, 2014, 3:58:15 PM6/26/14
to rav...@googlegroups.com
I'm running a patch command to increment a counter on a doc.  If the doc doesn't exist yet, i want to create it.  
It seems like this is what i want:

RavenJObject Patch(string key, ScriptedPatchRequest patchExisting, ScriptedPatchRequest patchDefault, RavenJObject defaultMetadata);

Am I understanding correctly that the "patchDefault" will be called if the document with id 'key' doesn't exist?
If so, am i responsible for creating the document using PutDocument in the patchDefault script?  Or will a blank doc be created with that id, and my script is responsible for filling in all of the required properties?

Below is my unsuccessful attempt at making this work, can someone tell me what's wrong (or point me to a working example)?     

Thanks.

 void Test()
 
{

     
var store = new EmbeddableDocumentStore {RunInMemory = true};
     store
.Initialize();

     
var docId = "Docs/1";
     
var patchExisting = new ScriptedPatchRequest
     
{
         
Script = "this.Counter++;",
     
};

     
var patchDefault = new ScriptedPatchRequest
     
{
         
Script = "this.Counter=100;",
     
};
     store
.DatabaseCommands.Patch(docId, patchExisting, patchDefault, new RavenJObject());
 
}
 
class TestDoc
 
{
   
public int Counter { get; set; }
 
}

The code above throws the following exception:

System.NullReferenceExceptionObject reference not set to an instance of an object.

   at Raven.Database.DocumentDatabase.RemoveReservedProperties(RavenJObject document) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 984   at Raven.Database.DocumentDatabase.RemoveMetadataReservedProperties(RavenJObject metadata) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 977   at Raven.Database.DocumentDatabase.Put(String key, Etag etag, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 767   at Raven.Database.DocumentDatabase.<>c__DisplayClass105.<ApplyPatchInternal>b__102(IStorageActionsAccessor actions) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 1994   at Raven.Storage.Managed.TransactionalStorage.Batch(Action`1 action) in c:\Builds\RavenDB-Stable\Raven.Database\Storage\Managed\TransactionalStorage.cs: line 126   at Raven.Database.DocumentDatabase.ApplyPatchInternal(String docId, Etag etag, TransactionInformation transactionInformation, Func`3 patcher, Func`1 patcherIfMissing, Func`1 getDocsCreatedInPatch, Boolean debugMode) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 1965   at Raven.Database.DocumentDatabase.ApplyPatch(String docId, Etag etag, ScriptedPatchRequest patchExisting, ScriptedPatchRequest patchDefault, RavenJObject defaultMetadata, TransactionInformation transactionInformation, Boolean debugMode) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 1891   at Raven.Database.Extensions.CommandExtensions.Execute(ICommandData self, DocumentDatabase database, BatchResult batchResult) in c:\Builds\RavenDB-Stable\Raven.Database\Extensions\CommandExtensions.cs: line 77   at Raven.Database.Extensions.CommandExtensions.ExecuteBatch(ICommandData self, DocumentDatabase database) in c:\Builds\RavenDB-Stable\Raven.Database\Extensions\CommandExtensions.cs: line 23   at Raven.Database.DocumentDatabase.ProcessBatch(IList`1 commands) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 2086   at Raven.Database.DocumentDatabase.<>c__DisplayClass111.<BatchWithRetriesOnConcurrencyErrorsAndNoTransactionMerging>b__10e(IStorageActionsAccessor _) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 2064   at Raven.Storage.Managed.TransactionalStorage.ExecuteBatch(Action`1 action) in c:\Builds\RavenDB-Stable\Raven.Database\Storage\Managed\TransactionalStorage.cs: line 166   at Raven.Storage.Managed.TransactionalStorage.Batch(Action`1 action) in c:\Builds\RavenDB-Stable\Raven.Database\Storage\Managed\TransactionalStorage.cs: line 145   at Raven.Database.DocumentDatabase.BatchWithRetriesOnConcurrencyErrorsAndNoTransactionMerging(IList`1 commands) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 2064   at Raven.Database.DocumentDatabase.Batch(IList`1 commands) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 2040   at Raven.Client.Embedded.EmbeddedDatabaseCommands.Batch(IEnumerable`1 commandDatas) in c:\Builds\RavenDB-Stable\Raven.Client.Embedded\EmbeddedDatabaseCommands.cs: line 709   at Raven.Client.Embedded.EmbeddedDatabaseCommands.Patch(String key, ScriptedPatchRequest patchExisting, ScriptedPatchRequest patchDefault, RavenJObject defaultMetadata) in c:\Builds\RavenDB-Stable\Raven.Client.Embedded\EmbeddedDatabaseCommands.cs: line 1085

Jason Aminto

unread,
Jul 7, 2014, 2:11:20 PM7/7/14
to rav...@googlegroups.com
Anybody know how this is supposed to work?

Kijana Woodard

unread,
Jul 7, 2014, 3:46:42 PM7/7/14
to rav...@googlegroups.com
Sorry. I mainly use ScriptedPatch. 

Maybe someone else can reply. I did want to mention that GMail is "warning" me to "be careful" your messages. Not sure why, since it looks like any other forum post, but that might explain the lack of response if it's getting filtered out for folks.


--
You received this message because you are subscribed to the Google Groups "RavenDB - 2nd generation document database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Oren Eini (Ayende Rahien)

unread,
Jul 7, 2014, 3:55:06 PM7/7/14
to ravendb
This is the first I see this message, yes.

What is the actual issue?



Oren Eini

CEO


Mobile: + 972-52-548-6969

Office:  + 972-4-622-7811

Fax:      + 972-153-4622-7811



Kijana Woodard

unread,
Jul 7, 2014, 4:01:45 PM7/7/14
to rav...@googlegroups.com
I copied this on behalf of the OP:

I'm running a patch command to increment a counter on a doc.  If the doc doesn't exist yet, i want to create it.  
It seems like this is what i want:

RavenJObject Patch(string key, ScriptedPatchRequest patchExisting, ScriptedPatchRequest patchDefault, RavenJObjectdefaultMetadata);

Am I understanding correctly that the "patchDefault" will be called if the document with id 'key' doesn't exist?
If so, am i responsible for creating the document using PutDocument in the patchDefault script?  Or will a blank doc be created with that id, and my script is responsible for filling in all of the required properties?

Below is my unsuccessful attempt at making this work, can someone tell me what's wrong (or point me to a working example)?     

Thanks.

 void Test()
 
{

     
var store = new EmbeddableDocumentStore {RunInMemory = true};
     store
.Initialize();

     
var docId = "Docs/1";
     
var patchExisting = new ScriptedPatchRequest
     
{
          
Script = "this.Counter++;",
     
};

     
var patchDefault = new ScriptedPatchRequest
     
{
         
Script = "this.Counter=100;",
     
};
     store
.DatabaseCommands.Patch(docId, patchExisting, patchDefault, new RavenJObject());
 
}
 
class TestDoc
 
{
    
public int Counter { get; set; }
 
}

The code above throws the following exception:

System.NullReferenceExceptionObject reference not set to an instance of an object.

   at Raven.Database.DocumentDatabase.RemoveReservedProperties(RavenJObject document) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 984   at Raven.Database.DocumentDatabase.RemoveMetadataReservedProperties(RavenJObject metadata) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 977   at Raven.Database.DocumentDatabase.Put(String key, Etag etag, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 767   at Raven.Database.DocumentDatabase.<>c__DisplayClass105.<ApplyPatchInternal>b__102(IStorageActionsAccessor actions) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 1994   at Raven.Storage.Managed.TransactionalStorage.Batch(Action`1 action) in c:\Builds\RavenDB-Stable\Raven.Database\Storage\Managed\TransactionalStorage.cs: line 126   at Raven.Database.DocumentDatabase.ApplyPatchInternal(String docId, Etag etag, TransactionInformation transactionInformation, Func`3 patcher, Func`1 patcherIfMissing, Func`1 getDocsCreatedInPatch, Boolean debugMode) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 1965   at Raven.Database.DocumentDatabase.ApplyPatch(String docId, Etag etag, ScriptedPatchRequest patchExisting, ScriptedPatchRequest patchDefault, RavenJObject defaultMetadata, TransactionInformation transactionInformation, Boolean debugMode) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 1891   at Raven.Database.Extensions.CommandExtensions.Execute(ICommandData self, DocumentDatabase database, BatchResult batchResult) in c:\Builds\RavenDB-Stable\Raven.Database\Extensions\CommandExtensions.cs: line 77   at Raven.Database.Extensions.CommandExtensions.ExecuteBatch(ICommandData self, DocumentDatabase database) in c:\Builds\RavenDB-Stable\Raven.Database\Extensions\CommandExtensions.cs: line 23   at Raven.Database.DocumentDatabase.ProcessBatch(IList`1 commands) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 2086   at Raven.Database.DocumentDatabase.<>c__DisplayClass111.<BatchWithRetriesOnConcurrencyErrorsAndNoTransactionMerging>b__10e(IStorageActionsAccessor _) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 2064   atRaven.Storage.Managed.TransactionalStorage.ExecuteBatch(Action`1 action) in c:\Builds\RavenDB-Stable\Raven.Database\Storage\Managed\TransactionalStorage.cs: line 166   at Raven.Storage.Managed.TransactionalStorage.Batch(Action`1 action) in c:\Builds\RavenDB-Stable\Raven.Database\Storage\Managed\TransactionalStorage.cs: line 145   at Raven.Database.DocumentDatabase.BatchWithRetriesOnConcurrencyErrorsAndNoTransactionMerging(IList`1 commands) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 2064   at Raven.Database.DocumentDatabase.Batch(IList`1 commands) in c:\Builds\RavenDB-Stable\Raven.Database\DocumentDatabase.cs: line 2040   at Raven.Client.Embedded.EmbeddedDatabaseCommands.Batch(IEnumerable`1 commandDatas) in c:\Builds\RavenDB-Stable\Raven.Client.Embedded\EmbeddedDatabaseCommands.cs: line 709   at Raven.Client.Embedded.EmbeddedDatabaseCommands.Patch(String key, ScriptedPatchRequest patchExisting, ScriptedPatchRequest patchDefault, RavenJObject defaultMetadata) in c:\Builds\RavenDB-Stable\Raven.Client.Embedded\EmbeddedDatabaseCommands.cs: line 1085

Oren Eini (Ayende Rahien)

unread,
Jul 7, 2014, 4:05:16 PM7/7/14
to ravendb
This should work, yes.

Can you create a full failing test for this?

Oren Eini (Ayende Rahien)

unread,
Jul 7, 2014, 4:05:38 PM7/7/14
to ravendb
Note that the patchDefault just need to _create_ the document, it doesn't need to persist it.

Jason Aminto

unread,
Jul 7, 2014, 11:33:38 PM7/7/14
to rav...@googlegroups.com
Thanks, Kijana.  I checked this thread out on a couple of different google accounts, and didn't see any warnings - weird.

Oren, below is my failing test using the ravendb test helpers.   I get the same NullReferenceException as posted previously when trying to execute the Patch.

 public class RavenTestSample : RavenTestBase
  {
        [Fact]
        public void PatchRequestShouldCreateDocIfNotExists()
        {
            using (var store = NewDocumentStore())
            {
                var patchExisting = new ScriptedPatchRequest
                {
                    Script = "this.Counter++;",
                };
                var patchDefault = new ScriptedPatchRequest
                {
                    Script = "this.Counter=100;",
                };
                var docId = "Docs/1";

                store.DatabaseCommands.Patch(docId, patchExisting, patchDefault, new RavenJObject());

                using (var session = store.OpenSession())
                {
                    Assert.NotNull(session.Load<TestDoc>(docId));
                }
            }
        }

        public class TestDoc
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "RavenDB - 2nd generation document database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "RavenDB - 2nd generation document database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Oren Eini (Ayende Rahien)

unread,
Jul 8, 2014, 4:03:15 AM7/8/14
to ravendb
Hi,
Thanks, I reproduced and fixed this issue.

A workaround for that is:


     
var patchDefault = new ScriptedPatchRequest
     
{

         
Script = @"
this.Counter=100;
this['@metadata'] = {};
",
     
};
Reply all
Reply to author
Forward
0 new messages