Using a IDocumentStoreListener to modify the saved entity is failing with InvalidOperationException

146 views
Skip to first unread message

marcus

unread,
May 2, 2012, 2:31:09 PM5/2/12
to rav...@googlegroups.com
I need to update an entity before it's saved, to modify it I need to use the documentsession and load another document and use it for calculating the value I need to change. When I do that I get an InvalidOperationException: Collection was modified; enumeration operation may not execute

Is this a big no no? This is my sample code http://cl.ly/GJJq

Itamar Syn-Hershko

unread,
May 2, 2012, 3:06:55 PM5/2/12
to rav...@googlegroups.com
It does look weird. What are you trying to do?

Oren Eini (Ayende Rahien)

unread,
May 2, 2012, 3:14:04 PM5/2/12
to rav...@googlegroups.com
You can't modify the session while you are inside the store listenwr

marcus

unread,
May 2, 2012, 3:39:43 PM5/2/12
to rav...@googlegroups.com
Ok, I solved it by adding the stuff i needed to the parent. I think it will work ok

Chris Marisic

unread,
May 2, 2012, 3:40:26 PM5/2/12
to rav...@googlegroups.com
I found this fact to be total crap when I was working with NHibernate and made NHibernate listeners entirely useless.

Why shouldn't you be able to load a document? I can understand not allowing MODIFYING loaded documents inside the listener but I certainly don't see why you can't get a copy of the document.

Chris Marisic

unread,
May 2, 2012, 3:42:49 PM5/2/12
to rav...@googlegroups.com
Some thoughts on possible work arounds, try using lower level APIs:

Session.Advanced.DatabaseCommands.Get()

ABSOLUTE worst case, you could probably make a direct web request to the server, the server would have no idea at that point.

Itamar Syn-Hershko

unread,
May 2, 2012, 6:09:30 PM5/2/12
to rav...@googlegroups.com
My personal take: this will encourage people to do stuff that is considered bad practice with RavenDB. If you want some other doc available to you, use Includes when you first loaded the original document, why issue 2 different commands? Or better - make sure to take this into account when modeling

Matt Warren

unread,
May 2, 2012, 6:10:11 PM5/2/12
to rav...@googlegroups.com
On Wednesday, 2 May 2012 20:40:26 UTC+1, Chris Marisic wrote:
I found this fact to be total crap when I was working with NHibernate and made NHibernate listeners entirely useless.

Why shouldn't you be able to load a document? I can understand not allowing MODIFYING loaded documents inside the listener but I certainly don't see why you can't get a copy of the document.

But for this to work wouldn't you have to ask the session to load a doc, but not track/cache it, otherwise it's always possible for it to be changed?

I guess you could use the low-level Advanced API's like you said in your other reply. Or if there was some way of saying to the session, that you want to load a doc, but don't track it, but I guess that's what the low-level API is for.
 

Oren Eini (Ayende Rahien)

unread,
May 3, 2012, 5:22:53 AM5/3/12
to rav...@googlegroups.com
I fixed this so this wouldn't throw, but it still had a lot of bad implications.
For example, the newly loaded entity will not be part of the current Unit of Work, so changes made to it won't be captured.


On Wed, May 2, 2012 at 10:40 PM, Chris Marisic <ch...@marisic.com> wrote:

Chris Marisic

unread,
May 3, 2012, 8:53:56 AM5/3/12
to rav...@googlegroups.com
The most primary use case for needing to load a document from the DB would be to load  User Document so you could insert denormalized data into the document you're saving.

On every system action I save the userid & username (denormalized, don't really care if they change it later it makes it easier for a human to understand if they look at history and see b...@site.com and not just userid:234347). I created a custom authentication system that exists outside of raven and allows me access to my full user object at all times, without having that functionality I could very well want to load a user document instead. (This was what I wanted to do in nhibernate but couldn't, and is part of the reason I built my auth system as I did, and by build i mean build on top of forms auth not roll my own entire security system)

Also I could see the use case similar to the OPs when working with hierarchical data that a change to a child object could theoretically need to change the parent object.

Itamar Syn-Hershko

unread,
May 3, 2012, 4:40:24 PM5/3/12
to rav...@googlegroups.com
Chris, for both scenarios mentioned I can see an easier way out -

For storing user data, just have that user entity handy by using Includes or saving the current user object in the HTTP session context

For hierarchical data, if changes made to a child document always affect the parent, you might want to store a large document to hold the hierarchy details instead of doing this within the entities themselves. Doing this, especially if that is a common operation, violates the transactional boundary
Reply all
Reply to author
Forward
0 new messages