You need to sign in to do that
Don't have an account?
James@KronosLab
Can't create objects in getter
I'm writing an application where I return a complex calculation as part of a getter on a page. For efficiency, I'd like to cache the results in a group of objects, and only recompute the value if the underlying data becomes 'dirty'
Unfortunately, it seems that there is a DML limit of 0 on getters, because if I try to create any objects at all, I get a "Too many DML Statements: 1" error.
You might want to remove this restriction, as cached computations are a highly useful way to reduce resource requirements.
James
Unfortunately, it seems that there is a DML limit of 0 on getters, because if I try to create any objects at all, I get a "Too many DML Statements: 1" error.
You might want to remove this restriction, as cached computations are a highly useful way to reduce resource requirements.
James
The "good" news: we provide a stateful programming model that makes
this kind of thing (along with multi request page user experiences (wizards for one) a snap to build). Instead of caching to the db you can store the expensive to calculate thing in a data member in your controller.
In your case it sounds like you might be looking for something less transient/shareable across users? I believe you can move your DML to your controller's constructor to avoid the no DML limit. You are thevfirst dev to provide a practical use case for lifting the restriction - not one I am particularly fond of either - stay tuned for an update on this...
I'll be a little more specific on the problem.
We're prototyping a timekeeping application. Totalizing timecards is too expensive (> 20 queries) to run as a trigger when the hours are first imported, so we want to totalize and cache on first request (we mark the timecard as dirty if any of the underlying data is changed, so we know to totalize the next time the timecard is requested.)
The page in question is a reporting tool. If we change the employee we're viewing, we want to retotalize the data. The cleanest way to do this is to design a utilty function that anyone can call to get either the cached or retotalized data, and then have the getter call it. But since getters can't create things, we can't cache the data back. The constructor for the controller won't work, because we may change employee several times once the controller is instantiated.
I can work around it for the moment (assuming I can get action calls on onchange events to work.) But it's a valid pattern to support.
James
Isn't that an event in the UI that should be calling the action to change/set the user context?
Why is that cleaner? Isn't the utility function an action here?
Yes, in this case. But what I'd really like to do is make a generic "get me the data, retotalizing if you need to" method, and call it whenever I need this data anywhere in the application. Otherwise, the caller needed to know how the data is being calculated, which should be really be encapsulated. The fact that asking for this value may result in database writes shouldn't need to be revealed to the caller.
See above.
James
One scenario I had envisioned that would also need DML in a getter is logging/audit trails. We bounced this thing around a number of times and decided to go out in Summer '07 with this restriction and planned to revisit if/when a real world need like yours materialized.
Nope, same zero DML restriction in the constructor...
James