Migration details for DynamoDB v2 in AWS Java SDK?

前端 未结 2 1032
猫巷女王i
猫巷女王i 2021-02-01 23:55

Has anyone made the change to the new namespaces (com.amazonaws.services.dynamodbv2) and interfaces for DynamoDB in the AWS Java SDK 1.4.2 (and later)? The release

2条回答
  •  广开言路
    2021-02-02 00:14

    DynamoDB AWS Java 1.4.1 => 1.4.2 (non-exhaustive) migration steps

    Well, I bit the bullet and did it. Here's my experience.

    First, change the DynamoDB namespace:

    • com.amazonaws.services.dynamodb => com.amazonaws.services.dynamodbv2

    The first thing you notice is there are types missing. The most major is Key is gone. Good riddance as it was too generic of a name. It is now replaced with Map which makes sense as keys become a lot more malleable with Local Secondary Indexes (LSI). Unfortunately, working with maps and generics in general sucks in Java (see Bonus at bottom). Gone are the fluent interfaces of withHashKeyElement / withRangeKeyElement.

    Next, very carefully find/replace the DynamoDB types which were replaced by generic collections:

    • com.amazonaws.services.dynamodb.model.Key => Map
    • com.amazonaws.services.dynamodb.model.BatchResponse => List>
    • com.amazonaws.services.dynamodb.model.KeySchema => List
    • (Probably others, these were the few I directly referenced.)

    Next, find everything that broke. This is a very manual process that requires knowing your code base and the SDK quite well. Specifically, you must know your key schema very well as it's all strings from here on. Luckily in my situation, the first two tasks were about 90% of the changes:

    • Find every new Map, it is an indication that Key was formerly there.
    • QueryRequest merged withHashKeyValue(AttributeValue) withRangeKeyCondition(Condition) into the mega withKeyConditions(Map) This method is the core change for LSI lets you specify things other than hash/range. What it accepts is more restrictive than the interface, but this is logical when you consider DynamoDB only lets you query indexed attributes.
    • DynamoDBQueryExpression became generic and changed its interface (not sure why).
    • KeySchemaElement no longer needs AttributeType, but now needs KeyType

    Finally, Compile and regression test your entire stack.

    P.S. While I was performing all this, version 1.4.4.1 was just released to Maven Central.


    Bonus

    Since Maps are the common solution to Java's lack of loosely typed classes, they are everywhere. A little helper lib can really go a long way toward building these less verbosely. Here are some bits of my helper:

    public class MakeJavaSuckLess { // TODO: find a shorter class name
        public static final float MAX_LOAD_FACTOR = 1.0f;
    
        /**
         * Builds a mutable Map from an interlaced sequence of key-value pairs
         * where keys are strings and values are VType objects
         * @param pairs
         * @return
         */
        public static  Map asMap(Object... pairs) {
            return mergeMaps(null, pairs);
        }
    
        /**
         * Builds a mutable Map from an interlaced sequence of key-value pairs
         * where keys are strings and values are VType objects
         * @param pairs
         * @return
         */
        public static  Map mergeMaps(Map map, Object... pairs) {
            final int length = (pairs != null) ? pairs.length/2 : 0;
            if (map == null) {
                // max out the load factor since most of these don't change
                map = new HashMap(length, MAX_LOAD_FACTOR);
            }
    
            for (int i=0; i

    Now creating your DynamoDB keys is slightly less ugly:

    Map key = MakeJavaSuckLess.asMap("hashKey", new AttributeValue("hashVal"), "rangeKey", new AttributeValue("rangeVal"));
    

    Type erasure in Java's generics makes this again uglier in places. You will sometimes need to explicitly specify VType:

    new GetItemRequest().withKey(MakeJavaSuckLess.asMap("hashKey", new AttributeValue("hashVal"), "rangeKey", new AttributeValue("rangeVal")));
    

提交回复
热议问题