An entity update that fails due to an non-allowed action should not do so silently

Posts   
 
    
Posts: 98
Joined: 10-Nov-2006
# Posted on: 18-Nov-2014 19:48:08   

LLBLGen 4.2, Adapter, SQL Server

With 4.2, the concept of an Allowed Action was introduced. I recently ran into a problem where I was trying to update an entity that was based on a SQL Server View. When I called adapter.SaveEntity(), I got no error, but the changes were not sent to the database. I had no idea why. I had to build a debug version of the LLBLGen and step though the code before I could determine the source of the problem.

Once I knew what the problem was, it was a simple matter to go into the designer and adjust the Allowed Actions to allow updates. The problem was the time it took to figure this out.

It would be my first preference that if I tried to save an entity and that save failed due to the action not being allowed, then I should get an Exception thrown. That way I would very quickly be able to discover my error and fix the situation.

If you can't change things to throw an Exception, then at least I would suggest that you adjust the logging to explain what has happened. I did turn on logging while I was trying to figure this problem out, but it doesn't mention anything about why the entity didn't save:


Method Enter: DataAccessAdapterBase.SaveEntity(4)
Active Entity Description: 
    Entity: Auctionpay.Aesop.AdapterData.EntityClasses.SaleElementViewEntity. ObjectID: 555e08ac-5a89-4a1e-85af-b0b7c8874f1e
    PrimaryKey field: SaleElementId. Type: System.Int32. Value: 1506
Method Enter: DataAccessAdapterBase.PersistQueue
Persistence action info: Action: Insert. Queue length: 0
PersistQueue method result: queuePersisted result: True
Method Exit: DataAccessAdapterBase.PersistQueue
Method Enter: DataAccessAdapterBase.PersistQueue
Persistence action info: Action: Update. Queue length: 1
Current persisted entity info: 
    Entity: Auctionpay.Aesop.AdapterData.EntityClasses.SaleElementViewEntity. ObjectID: 555e08ac-5a89-4a1e-85af-b0b7c8874f1e
    PrimaryKey field: SaleElementId. Type: System.Int32. Value: 1506
PersistQueue method result: queuePersisted result: True
Method Exit: DataAccessAdapterBase.PersistQueue
Method Exit: DataAccessAdapterBase.SaveEntity(4)

Thanks,

Wesley

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 19-Nov-2014 07:05:53   

See this related thread:[http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=23077](http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=23077)

David Elizondo | LLBLGen Support Team
Posts: 98
Joined: 10-Nov-2006
# Posted on: 19-Nov-2014 17:43:48   

Yes, I've read that thread. That thread talks about various ways to make sure that all of the entities have full CRUD permissions.

The problem that I had was that I didn't even know that the "Allowed Actions" feature was causing the problem.

The poster in the thread you mention also wishes that LLBLGen would throw an Exception and not silently ignore updates:

With the introduction of this new "Allowed Actions" feature, our project is now not committing data in certain scenarios where LLBLGen thinks it should only have "READ" access, and since it isn't throwing an exception upon attempting to create a new entity, you see how that can present a problem for us - especially when taking advantage of recursive saves where we are creating a bunch of data at once.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 19-Nov-2014 18:52:17   

So, did you limit the allowed action in the configuration? But you need to get an Exception?

If you want an exception, why not allowing the action, but limit it in the database, so you get a database exception.

the thing is that Allowed Actions mimics the authorizer as to when to return false and when not to, as mentioned in the docs.

Posts: 98
Joined: 10-Nov-2006
# Posted on: 19-Nov-2014 19:24:01   

I don't want to limit the Actions, it was a mistake that the entity's actions were limited. But this feature makes such a mistake hard to recover from.

Here's what happened:

1) I added a new view to my project via the designer 2) By default, it has only Read action allowed. But, I didn't know that, as I didn't know about this feature at that time. 3) I added code in my project to update the new entity based on the view. 4) I ran the program. I found that the view was not updated. But I had no idea why. I spent a long time trying to determine why. I had to eventually download the LLBLGen source code, build a debug version and step though the LLBLGen code to determine why the entity was not saved.

So, this new feature has introduced a situation where LLBLGen silently ignores my request to save the entity. This is a problem because:

1) It's not obvious that something has gone wrong. Since no exception is thrown, the developer has to rely on testing to realize that the changes are not being saved. 2) Once you do find out that something is wrong, there's no clues that point in the direction of the "Allowed Action" as being the culprit.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 20-Nov-2014 07:04:43   

I think that it wasn't easy to figure thos out because it's a new feature. Anyway, I will pass your comment to the LLBLGen Team to see if it would be considered as a possible enhancement.

David Elizondo | LLBLGen Support Team
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 20-Nov-2014 10:39:27   

I understand your complaint and I would react the same as you did. The problem is however that throwing an exception isn't consistent: a save which is denied by an authorizer also doesn't throw an exception, it's ignored: the idea behind the feature is that a changed entity which has only 'readonly' set as allowed actions is seen as 'not changed', and thus ignored.

But that of course clashes with your situation where you weren't realizing this was going on.

I'm not sure how to address this. I'm leaning towards documenting this as a breaking change (as it is for view targeting entities: they can't be saved by default), but not sure whether that would have helped, but it's better than nothing I suppose. I don't really want to change the behavior to raise exceptions, also because that is introducing a breaking change for v4.2 after RTM. Additionally, we could make the default for entities targeting views the same as for entities targeting tables, but that also feels wrong.

Making throwing an exception on this configurable (and by default have it 'off' as otherwise it's a breaking change) won't help anymore, as people who don't know about the feature won't switch the exception throwing on and thus have the same problem, and people who do know about the exception throwing setting will thus also know about the feature and it will solve itself.

Any ideas?

Frans Bouma | Lead developer LLBLGen Pro
Posts: 98
Joined: 10-Nov-2006
# Posted on: 20-Nov-2014 17:21:59   

Frans,

Thanks for your comments. I don't use authorizers in my code, so I wasn't aware that the "allowed actions" feature was following that same pattern. I also sympathize with the position you're in as far as throwing an exception. I'm not surprised that you said that it couldn't be done without putting in yet another breaking change simple_smile

If throwing Exceptions is off the table, then my suggestion would be to add logging statements that would explain why the save was being skipped. Turning on logging was my first instinct when I saw this problem, and if that output had mentioned "Allowed Combinations", then that would have given me a place to start looking for answers. I would then have found the "Concepts - Action Combinations" section in the Documentation, which provides a good description of the feature.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 20-Nov-2014 17:57:03   

Good point about logging. We can add info to a tracer about this. So add info to one of the tracers (the ormpersistence tracer for example) and a breaking change remark, I think that will give enough information for users to be able to find the reason why saves fail. Will add this to the designer so it will show up in the next build simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 24-Nov-2014 11:22:23   

ORMPersistenceExecution trace now logs deny actions for authorizers and action combinations (separately, so you know if it's an authorizer or action combination), at level 3 (verbose also logs this of course, but level 3 is preferable, as verbose really floods the tracer)

example:

Method Enter: DataAccessAdapterBase.PersistQueue SaveEntity: Entity of type 'ActionTestCREntity' not saved because Allowed Action Combinations for this entity doesn't contain action 'Update'. Method Exit: DataAccessAdapterBase.PersistQueue

Available in next build.

Frans Bouma | Lead developer LLBLGen Pro