5

I would know if there is some way to maintain state across different transactions without using View State.

For example, if in my Custom Controller, for every action method, I need 100 Account's records, right now, I can follow two ways:

  1. Use static/transient keyword on this list. In this way, the View State doesn't contain my Account's records but I have to execute a SOQL every time I go on the server-side.
  2. Don't use static/transient keyword on this list. In this way, I have not to execute a SOQL every time I go on the server-side but I could have a problem with the View State.

Is there any way to store and keep information across different transaction not using the View State? The only idea I got is using Platform Cache. Is it correct? Other solution available?

Thanks!

7

The exact solution depends on the situation. You shouldn't think solutions as "either-or," as there's often an opportunity for hybrid solutions. There's also a few bonus solutions you can use depending on circumstances.

For example, you might choose to store just the record ID values in a list, and make a transient list for the records. Yes, you'll have to query the database each transaction, but you're trading some state for some performance.

Or, you might choose to use apex:inputHidden and bind the record variables to these inputs. Variables bound to input fields can be transient. So, conceptually, you should be able to do this:

<apex:repeat value="{!accounts}" var="rec">
  <apex:inputHidden value="{!rec.Id}" /><apex:inputHidden value="{!rec.Name}" />
</apex:repeat>

I haven't tried this model before, but I've used it similarly on Boolean values, String values, etc with success to reduce view state. You could even JSON serialize the data and put it in an apex:inputHidden.

This has a much larger limit, about 15,000,000 bytes of data (including serialization), allowing you to store relatively large amounts of data without any view state at all.

Platform Cache is nice, but you have to be prepared to do a query anyways, as it can expire at any time (the cache is not guaranteed to survive through its TTL).

In other words, there are solutions that you can use aside from pure view state or pure query methods.

| improve this answer | |
  • 2
    +1 from me, love the JSON serialize idea! – codeyinthecloud Nov 12 '18 at 16:16
1

When Can I Use Platform Cache?

You can use Platform Cache in your code almost anywhere you access the same data over and over. Using cached data improves the performance of your app and is faster than performing SOQL queries repetitively, making multiple API calls, or computing complex calculations.

The best data to cache is:

  1. Reused throughout a session, or reused across all users and requests
  2. Static (not rapidly changing)
  3. Expensive to compute or retrieve

Store Data That Doesn’t Change Often

Use the cache to store static data or data that doesn’t change often. This data is initially retrieved through API calls from a third party or locally through SOQL queries. If the data changes, cache this data if the values don’t have to be highly accurate at all times.

Store Data Obtained from Complex Calculations

Values that are a result of complex calculations or long queries are good candidates for cache storage. Examples of such data are:

  1. Total sales over the past week
  2. Total volunteering hours company employees did as a whole
  3. Top sales ranking

For clues on where to use Platform Cache, inspect your code. For example, do you currently store app data by overloading a Visualforce view state? These stored values are all candidates for Platform Cache.

Not every use case is a Platform Cache use case. For example, data that changes often and that is real-time, such as stock quotes, isn’t a good candidate for caching. Also, ensure you familiarize yourself with Platform Cache limitations. For example, if your data is accessed by asynchronous Apex, it can’t be stored in a cache that is based on the user’s session.

Keep in mind these considerations when working with Platform Cache.

  1. Cache isn’t persisted. There’s no guarantee against data loss.
  2. Some or all cache is invalidated when you modify an Apex class in your org.
  3. Data in the cache isn’t encrypted.
  4. Org cache supports concurrent reads and writes across multiple simultaneous Apex transactions. For example, a transaction updates the key PetName with the value Fido. At the same time, another transaction updates the same key with the value Felix. Both writes succeed, but one of the two values is chosen arbitrarily as the winner, and later transactions read that one value. However, this arbitrary choice is per key rather than per transaction. For example, suppose one transaction writes PetType="Cat" and PetName="Felix". Then, at the same moment, another transaction writes PetType="Dog" and PetName="Fido". In this case, the PetType winning value could be from the first transaction, and the PetName winning value could be from the second transaction. Subsequent get() calls on those keys would return PetType="Cat" and PetName="Fido".
  5. Cache misses can happen. We recommend constructing your code to consider a case where previously cached items aren’t found. Alternatively, use the CacheBuilder Interface, which checks for cache misses.
  6. Session cache doesn’t support asynchronous Apex. For example, you can’t use future methods or batch Apex with session cache.
  7. Partitions must adhere to the limits within Salesforce.
  8. The session cache can store values up to eight hours. The org cache can store values up to 48 hours.
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.