Skip to content

Use Hash Range keys

Sebastian J edited this page Feb 10, 2016 · 10 revisions

Using a Range and Hash as a combined key requires a little bit more code to leverage AWS SDK for DynamoDB and Spring-Data:

  • In the entity have a field annotated with @Id referencing a custom "key" class - and exposes the attributes as direct getters/setter with the @DynamoDBHashKey / @DynamoDBRangeKey annotation including the column configuration.
@DynamoDBTable
public class Playlist {
	@Id
	private PlaylistId playlistId;

	// Any other field and their getter/setter + @DynamoDBAttribute annotation

	@DynamoDBHashKey(attributeName = "UserName")
	public String getUserName() {
		return playlistId != null ? playlistId.getUserName() : null;
	}

	public void setUserName(String userName) {
		if (playlistId == null) {
			playlistId = new PlaylistId();
		}
		playlistId.setUserName(userName);
	}

	@DynamoDBRangeKey(attributeName = "PlaylistName")
	public String getPlaylistName() {
		return playlistId != null ? playlistId.getPlaylistName() : null;
	}

	public void setPlaylistName(String playlistName) {
		if (playlistId == null) {
			playlistId = new PlaylistId();
		}
		playlistId.setPlaylistName(playlistName);
	}    
  • The key class itself has only the hash and range member fields including the @DynamoDBHashKey / @DynamoDBRangehKey annotation again - this time without table column configuration.
public class PlaylistId implements Serializable {
	private static final long serialVersionUID = 1L;

	private String userName;
	private String playlistName;

	@DynamoDBHashKey
	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	@DynamoDBRangeKey
	public String getPlaylistName() {
		return playlistName;
	}

	public void setPlaylistName(String playlistName) {
		this.playlistName = playlistName;
	}
}
  • This also means that the generic for the Repository have to be updated to the new "key" class.
public interface PlaylistRepository extends CrudRepository<Playlist, PlaylistId> {
}

An example can be found in this test case with the entity class Playlist / ID class PlaylistId.

The background for this mumbojumbo is that Spring-Data requires to have a dedicated entity representing the key. As the Repository.find() method takes exactly one argument - T from the specific derived repository. Therefore the two fields, which constitute the key, have to be wrapped up in a single entity - the "key class" depicted above.

Clone this wiki locally