Java object references with cache layer

java, object, pass-by-reference, pass-by-value, reference

Solution

This is a problem with mutable state. It isn't only caching, it's any time you could have multiple references to the same object and that object is mutable. For example:

HashMap map = new HashMap();
map.put("one", new OrderItem());
OrderItem one = map.get("one");
OrderItem two = map.get("one");
one.setStatus(1);
two.setStatus(2);

Will have exactly the same problem. This becomes even more complicated when you have a concurrent environment. One way to solve this is to only have immutable objects. That way, if you want an object with different state, you're going to have to make a new one. It also makes concurrent programming easier.

You're right to consider copying the object. Your options are:

- Cloning

- Deep copying via serialization

- Deep copying via copy constructors

Each has their strengths and weaknesses and which one works best will depend on your environment.

Problem

We've created a caching layer to our J2EE-application. In this instance we use Ehcache. This has created a few challenges. Let's take this example. ``` OrderItem orderitem = cache.getOrderItemByID("id"); OrderItem old_orderitem = cache.getOrderItemID("id"); orderitem.setStatus(1); old_orderitem.setStatus(2); ``` If we're not carefull, any changes made to either of those objects will affect the other (they reference the same object). Saving orderitem back to the dabase would make it have status=2 How would we solve this the best way? We've tried making a .copyObject() method to each object. Which just creates a new object and sets all the values. But this doesn't seem like a good solution. The example was just to illustrate. The code is far more complex than that, but the result is the same. **********************Update 15.07.2010 ************************************************** In EHCache 2 there are some options to to turn on copyRead() and copyWrite(). And this solves all my problems :)

Original source