2

I am trying to delete a field called "dog" from all of the items that resides on table animals, or that I use the following code:

    Table table= dynamoDB.getTable("animals");
    ScanRequest scanRequest = new ScanRequest().withTableName("animals");
    ScanResult result = client.scan(scanRequest);


    for (Map<String, AttributeValue> item : result.getItems()){

        table.updateItem(new PrimaryKey("<Primary partition key name>", item.get("<Primary partition key name>"),"<Primary sort key name>", item.get("<Primary sort key name>")), 
new AttributeUpdate("dog").delete());

    }

But I am getting:

    Exception in thread "main" java.lang.RuntimeException: value type: class com.amazonaws.services.dynamodbv2.model.AttributeValue
.
.
.
    Caused by: java.lang.UnsupportedOperationException: value type: class com.amazonaws.services.dynamodbv2.model.AttributeValue

What am I doing wrong here?

by the way, I also tried:

   UpdateItemSpec updateItemSpec = new UpdateItemSpec()
                    .withPrimaryKey("<Primary partition key name>", item.get("<Primary partition key name>"),"<Primary sort key name>", item.get("<Primary sort key name>"))
                    .withUpdateExpression("REMOVE dog");
            table.updateItem(updateItemSpec);

But got the same exception. (Also tried DELETE instead of REMOVE)

2 Answers 2

1

You are using the old V1 DynamoDB API, which is not best practice. It better practice to use the Amazon DynamoDB V2 Java API.

The AWS SDK for Java 2.x is a major rewrite of the version 1.x code base. It’s built on top of Java 8+ and adds several frequently requested features. These include support for non-blocking I/O and the ability to plug in a different HTTP implementation at run time.

If you are not familiar with the AWS SDK for Java V2, see:

Get started with the AWS SDK for Java 2.x

For this use case (which is modifying an item), the solution is to use the Enhanced Client, which lets you map Java objects to a table. For more information, see:

Mapping items in DynamoDB tables

Using the Enhanced Clint, you can modify an item with code like this:

    package com.example.dynamodb;


import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.Key;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import java.time.Instant;


/*
 * Prior to running this code example, create an Amazon DynamoDB table named Customer with these columns:
 *   - id - the id of the record that is the key
 *   - custName - the customer name
 *   - email - the email value
 *   - registrationDate - an instant value when the item was added to the table
 *  Also, ensure that you have setup your development environment, including your credentials.
 *
 * For information, see this documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */

public class EnhancedModifyItem {

    public static void main(String[] args) {


        String usage = "Usage:\n" +
                "    UpdateItem <key> <email> \n\n" +
                "Where:\n" +
                "    key - the name of the key in the table (id120).\n" +
                "    email - the value of the modified email column.\n" ;

       if (args.length != 2) {
            System.out.println(usage);
            System.exit(1);
       }

        String key = args[0];
        String email = args[1];
        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
                .region(region)
                .build();

        DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(ddb)
                .build();

        String updatedValue = modifyItem(enhancedClient,key,email);
        System.out.println("The updated name value is "+updatedValue);
        ddb.close();
    }


    public static String modifyItem(DynamoDbEnhancedClient enhancedClient, String keyVal, String email) {
        try {
            //Create a DynamoDbTable object
            DynamoDbTable<Customer> mappedTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));

            //Create a KEY object
            Key key = Key.builder()
                    .partitionValue(keyVal)
                    .build();

            // Get the item by using the key and update the email value.
            Customer customerRec = mappedTable.getItem(r->r.key(key));
            customerRec.setEmail(email);
            mappedTable.updateItem(customerRec);
            return customerRec.getEmail();

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
        return "";
    }
}

You can find this V2 example and others for Amazon DYnamoDB here:

https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/javav2/example_code/dynamodb

Sign up to request clarification or add additional context in comments.

6 Comments

Hi, Thanks for you answer! I am actually using dynamodbv2, ie: "com.amazonaws.services.dynamodbv2.AmazonDynamoDB". Note that my question is how to delete a value within an item but not the item itself.
dynamodbv2 is still V1. Note that any package starting with com.amazonaws.services... is v1. V2 packages are software.amazon.awssdk.services.dynamodb...
Oh I missed that! thanks. Now I just need to find out how to delete a property value within an item.
Have you tried to update that item without the specific column value.
See this code - using the Enhanced Client for the DynamoDB API to modify an item.
|
0

I found the solution for the issue, I cant believe I missed it.... Remember kids, its mandatory to look at the actual values when debugging!

So instead of using just:

item.get("<property name>")

You need to explicitly ask for a String like so:

item.get("<property name>").getS()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.