Spring Cache - Part 2 - Cache Keys

In part 1 of the post, we looked at how data can be cached through simple configuration. In this part, we are going to explore the cache keys.

Spring Cache - Part 1 - Introduction

Caching is an extremely important aspect of applications that care about lower latencies. There are a multitude of rules one has to adhere to while setting up a cache, in order to optimize the performance; but not overdo it. We will not get into those details in this post. Our focus would be on what Spring provides to enable caching in your applications.

JSON Property Name Customization in Jackson using PropertyNamingStrategy

Jackson is one of the most popular java libraries for serialization/deserialization of POJOs to/from JSON. By default, Jackson derives the JSON element names from the getter/setter method names of the POJO. e.g. getActorName() is translated to actorName in the resulting JSON.

How to Timeout JDBC Queries

JDBC queries by default do not have any timeout, which means that a query can block the thread for an unlimited amount time; of course, depending upon the DB load and the cost of the query. It is a good practice to timeout these queries if they can take longer than a certain amount of time.

Timeout on individual Queries

JDBC statements can be configured for timeouts, in seconds. When timeouts are set, the driver would wait for the given number of seconds for the query to execute (i.e. executeQuery and executeUpdate) and throw an SQLTimeoutException if doesn't respond within that time.

Here are a couple of examples.

Statement stmt = connection.prepareStatement("SELECT * FROM BOOKS");
stmt.setQueryTimeout(10);//Timeout of 10 seconds

//This would throw an SQLTimeoutException if it exceeds 10 seconds
ResultSet result = stmt.executeQuery();

PreparedStatement stmt = connection.prepareStatement("UPDATE BOOKS SET RETURNED = ? WHERE BID = ?");
stmt.setBoolean(1, true);
stmt.setString(2, "B1234");
stmt.setQueryTimeout(5);//Timeout of 5 seconds
//This would throw an SQLTimeoutException if it exceeds 5 seconds

Global Timeout (JDBC Driver Level)

If you need to set the same timeout for all query executions, then it can be set directly on the drivers. However, the options would differ from driver to driver.
Here is an example of timeouts set on the Oracle Thin Driver

Properties properties = new Properties();
properties.setProperty("user", "scott");
properties.setProperty("password", "tiger");
//This timeout is in milliseconds, but can vary for other drivers
properties.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_READ_TIMEOUT, "2000");
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@host:1521:SID", properties);

Spring JDBC timeouts

If you are using Spring JDBC, where you do not have direct control over the JDBC statements, JDBCTemplate also provides an option to setQueryTimeOut. If set to -1, it takes the JDBC driver's default setting for timeouts (which is covered above).
getJdbcTemplate().update("UPDATE BOOKS ...", sqlParamSource);

Tarlog - Eclipse Plugin for Windows

Tarlog is a plugin for eclipse that provides some useful features if you are working on a Windows machine. It allows you to Copy Path, Open Shell or Open Explorer on the selected file or folder in the project. It also allows changing the font of the editor through Ctrl++ and Ctrl-- keys.

Overriding Spring Beans with Aliases

The most common approach followed for overriding a spring bean is to define a new bean, with the same id as the original bean, in a separate XML file. During context initialization, Spring would register the last bean found for the id, and use it for all the injections.

I dislike this approach for two reasons.

ETags and Browser Cache

Caching resources on the browser is crucial to minimize unnecessary trips to the server and reduce the load on it. This works well for data that is static. But, there are cases where the data changes every once in a while (although less frequently), and you would want the browser to get the latest data without waiting for the cached data to expire. e.g., consider a scenario where a new version of the application is deployed with changes to CSS and javascript, and you want the user to experience these changes without forcing them to refresh their cache manually. One option you might consider is to make these resources non-cacheable and compromise the page performance a bit. Entity tags( or ETags for short) help you cache such resources, without the performance compromise.

How does @ModelAttribute Work?

@ModelAttribute is a Spring-MVC annotation that is used for preparing the model data. It is also used to define the command object for binding the HTTP request data. The annotation works only if the class is a Controller class (i.e. annotated with @Controller).

ModelAttribute can be applied to both methods as well as method-parameters. It accepts an optional "value", which indicates the name of the attribute. If no value is supplied to the annotation, then the value would default to the return type name in case of methods and parameter type name in case of method-parameters.

The way Spring processes this annotation is,