Storing Data in SimpleDB
Now that we have created a domain, the next thing to do is store some data in it. I've already mentioned that data is stored as items that have one or more attributes. StoreTrivialData.java (available here) starts by creating an item whose name is Vermont and which has two attributes whose name-value pairs are Abbreviation:VT and Nickname:Green Mountain State. Here is the code in method addData() that creates the item:
String stateName = "Vermont";
List<ReplaceableAttribute> attributeListVT =
new ArrayList<ReplaceableAttribute>();
attributeListVT.add(new ReplaceableAttribute("Abbreviation",
"VT", false));
attributeListVT.add(new ReplaceableAttribute("Nickname",
"Green Mountain State", false));
PutAttributesRequest putAttributesRequestVT =
new PutAttributesRequest(DOMAIN_NAME, stateName,
attributeListVT);
PutAttributesResponse response =
client.putAttributes(putAttributesRequestVT);
We start by creating a list of ReplaceableAttribute objects, each of which is created by passing the attribute name and value to the constructor. The third parameter, false in our case, is a boolean that specifies whether the value should replace all existing values.
After we invoke method addData() which contains the code above, we next invoke method addMoreData(). This method is almost identical to the addData() method but notice that it can accommodate the fact that the state of Connecticut has two nicknames, the Nutmeg State and the Constitution State. Two attributes, each having a name of nickname but with different values are associated with the item Connecticut. This demonstrates the point I made earlier that a given cell can have more than one value so in effect the domain can be viewed as a 3D spreadsheet where the item names along the Y axis, the attribute names along the X axis and all attributes that have an identical X value stack on the Z axis.
After each of the two methods stores its data, it invokes the displayAttributesForState() method, which uses the following code to display all of the attributes that are found for the item having the name of the specified state:
GetAttributesRequest getAttributeRequest =
new GetAttributesRequest();
getAttributeRequest.setDomainName(DOMAIN_NAME);
getAttributeRequest.setItemName(stateName);
GetAttributesResponse attributesReponse =
client.getAttributes(getAttributeRequest);
if (attributesReponse.isSetGetAttributesResult()) {
GetAttributesResult attributesResult =
attributesReponse.getGetAttributesResult();
List<Attribute> attributeList =
attributesResult.getAttribute();
System.out.println();
System.out.println(Integer.toString(attributeList.size()) +
" attributes found for " + stateName);
for (Attribute attribute : attributeList) {
if (attribute.isSetName()) {
System.out.println("Attribute: " +
attribute.getName());
}
if (attribute.isSetValue()) {
System.out.println("Value: " +
attribute.getValue());
}
}
}
When you run the program, it produces the following output:
writing attributes for item Vermont 0 attributes found for Vermont writing attributes for item Connecticut 4 attributes found for Connecticut Attribute: Nickname Value: Constitution State Attribute: Nickname Value: Nutmeg State Attribute: Area Value: 5544 Attribute: Abbreviation Value: CT
But what happened to the data for Vermont? Did the program fail? The message "writing attributes for item Vermont" indicates that the putAttributes() method was invoked and there are no messages indicating that an exception was thrown. So what's going on? The explanation is that SimpleDB was designed to be "eventually consistent". To see that this is true, let's modify the code to comment out both calls to putAttributes() and rerun the program. When you do, you see the following output:
domain has already been created 2 attributes found for Vermont Attribute: Nickname Value: Green Mountain State Attribute: Abbreviation Value: VT 4 attributes found for Connecticut Attribute: Nickname Value: Constitution State Attribute: Nickname Value: Nutmeg State Attribute: Area Value: 5544 Attribute: Abbreviation Value: CT
The absence of the "storing attributes" messages indicates that no data was written (we commented out the calls to putAttributes()) and yet the attributes that were seemingly missing are accounted displayed. So, the first time we ran the program, some attributes were indeed unavailable but the domain did attain "eventual consistency". This is not a design flaw but rather a design point. It means that if your application relies on data being available immediately after being written, then you should either use another mechanism for persisting your data or, if some delay can be tolerated, you could build in checks for consistency after you write your but before you attempt to access it.
Since we are looking at characteristics of SimpleDB, I should point out another; not every item must be assigned a set of attributes that is identical to any or all of the other items. Notice that Vermont has an Area attribute but Connecticut does not. This characteristic is often referred to as "sparse population". It takes some getting used to but really simplifies things. In the relational database world, if data is missing for a field, you must specify a null value; when you are using SimpleDB, if an attribute is missing you simply don't record it.


