Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RavenDB tracked changes bypasses validation

Tags:

ravendb

I am playing around trying to get an application framework going that uses RavenDB. I have setup a business logic service, which has a 1 to 1 relationship with a session and effectively becomes the unit of work abstraction.

Part of the business logic service would be to contain all the validation. A method from the service might be something like

    public void StoreUser(User user)
    {
        //Some validation logic
        if(string.IsNullOrWhiteSpace(user.Name))
            throw new Exception("User name can not be empty");

        Session.Store(user);
    }

The issue is that because user is tracked as soon as it is stored i can bypass any validation on the store method but storing a correct value then changing it later

    public void TestUserStore()
    {
        var u1 = new User() {Name = "John"};
        var u2 = new User() { Name = "Amy" };

        Service.StoreUser(u1);
        u1.Name = null; //change is tracked and will persist on the next save changes
        Service.StoreUser(u2);
        Service.SaveChanges();

        //The following fails, as we have stored null as the name rather than "John" bypassing our validation
        Assert.IsTrue(Service.AdhocQuery<User>().Any(u => u.Name == "John"));

    }

Is there someway to get RavenDB to store only a snapshot of the item that was stored and not track further changes? Should i be cloning everything going into and out of the business logic service to prevent illegal update? or am i doing the validation in the wrong place is there a better place to put this logic?

like image 922
Alex Avatar asked Oct 02 '12 18:10

Alex


1 Answers

Put your validation logic inside a IDocumentStoreListener before every save, you can do this sort of check automatically.

I blogged more about this issue here.

like image 152
Ayende Rahien Avatar answered Oct 29 '22 13:10

Ayende Rahien