readOnly attribute on the <cacheModel> tag to true in an environment that is a
read-write environment. Additionally, we set serialize to false to eliminate the
burden of the deep copy. That means that objects that are retrieved from the
cache may be altered. This is a safe approach for several reasons. First, only the
person managing the cart will be altering product objects. The users who are
actually shopping will never change the product object through their actions.
Second, whenever a product update occurs, the cache is flushed. Finally,
specifying the reference-type property as WEAK will not allow products to hang
around very long because it discards them at the discretion of the garbage
collector. Listing 9.10 shows an example of our cache model configuration.
Cache model for productCache
<cacheModel id="productCache" type="MEMORY"
<flushOnExecute statement="Product.add" />
<flushOnExecute statement="Product.edit" />
<flushOnExecute statement="Product.remove" />
<property name="reference-type" value="WEAK" />
We can now use the defined <cacheModel> from a query mapped statement. We
tell the getProductById query mapped statement to use productCache by specify-
ing it in the cacheModel . Whenever the getProductById select is called from the
application, the cached product object will be retrieved according to the specifica-
tions of the productCache cache model. Listing 9.11 shows a simple example of
how a <select> statement can take advantage of the defined <cacheModel> .
Query mapped statement that uses productCache
<select id="getProductById" resultClass="Product"
SELECT * FROM Product WHERE productId=#productId#
Caching aging static data
This final case study is a somewhat unusual situation, but it's a fun test case none-
theless. Situations arise where you need to deal with smaller static portions of data
that become less relevant as time goes on. Often this type of caching is associated
with time-based analytics. Examples of time-based analytics include performance