How to read data from AWS DynamoDB using spring boot

Sun, Apr 26, 2020

Read in 5 minutes

In this article, you will learn how to use the AWS DynamoDB service and how to create a table and fill the values and finally, you will learn to read the data from DynamoDB using spring boot web application.

TABLE OF CONTENT :

  1. AWS DynamoDB introduction
  2. Create table and insert values in DynamoDB
  3. Steps to connect DynamoDB from spring boot application
  4. Possible exceptions and errors
  5. Conclusion

1. AWS DynamoDB Introduction:

DynamoDB is a NoSQL database (Non-Relational Database ) with key-value pairs. Using AWS DynamoDB you can create a table and that table can be exposed as a web service. We can connect with dynamo DB programmatically. For that, you need an Access ID and secret key.

To get an Access ID and key, login into your AWS free tier account and click My security credentials option.

IAM_Management_Console1

Click on create a new access key, the system will give you the generated access id and key.

IAM_Management_Console2

2. Create A Table And Insert Values In Dynamodb:

To create a table in DynamoDB, select DynamoDB services, and click on “create table“. You will get the below screen and enter the table name and Partition key. You can consider this Partition key as a primary key in the NoSQL database. But this Partition key is having some difference when you compare with the primary key.

DynamoDB_AWS_table2

To add values to the table, click on “create item” and click the append and add the type and value.

DynamoDB_AWS_table6

THE TABLE WITH VALUES :

DynamoDB_AWS_table7

3. Steps To Connect DynamoDb From Spring Boot Application :

1. Create a spring boot project

Create a spring boot project from spring boot initializer and add spring web dependency.

springStarterproject

Adding spring web dependency,

springbootstarter

2. Add dependencies for AWS Dynamo DB

<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-dynamodb</artifactId>
<version>1.11.764</version>
</dependency>

<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-bom</artifactId>
<version>1.11.614</version>
<type>pom</type>
<scope>import</scope>
</dependency>

3. Create DynamoDBMapper and DynamoDB client (DynamoDBConfiguration)

@Configuration
public class DynamoDBConfiguration {
Logger logger = LoggerFactory.getLogger(ProductController.class);
@Bean
    public DynamoDBMapper dynamoDBMapper() {
//AmazonDynamoDB client1 = AmazonDynamoDBClientBuilder.standard().build();
logger.info("DynamoDBConfiguration ");
        AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("access ID", "key")))
                .withRegion(Regions.US_EAST_1)
                .build();
        logger.info("DynamoDBConfiguration "+client);

        return new DynamoDBMapper(client, DynamoDBMapperConfig.DEFAULT);
    }

}

4. Create controller

You have to create a rest controller to expose the dynamo DB table and you have to do request mapping and make a call to service.

Here the table name is Product and we are passing pid to get the values for that.

And you have to handle the Amazon service exception.

@RestController
public class ProductController {
private ProductService productservice;
@Autowired
public ProductController(ProductService productservice) {
        this.productservice = productservice;
    }
Logger logger = LoggerFactory.getLogger(ProductController.class);

@RequestMapping(value = "/Product/{pid}", produces = {"application/json"}, method = RequestMethod.GET)
    public ResponseEntity<Product> readProduct(@PathVariable String pid) {
logger.info("pid  "+pid);
        try {

        logger.info("pid aaa "+pid);
            Product response = productservice.readProduct(pid);

            logger.info("pid bbb "+pid);

            return ResponseEntity.status(HttpStatus.OK).body(response);
        } catch (AmazonServiceException e) {
            throw new ResponseStatusException(HttpStatus.valueOf(e.getStatusCode()), e.getMessage(), e);
        } catch (AmazonClientException e) {
            throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage(), e);
        }
    }

}

5. Create a POJO class :

You have to create a POJO class for the table.

Product.java

@Component
@DynamoDBTable(tableName = "Product")
public class Product {

	@DynamoDBHashKey(attributeName = "pid")
	private String pid;
	@DynamoDBAttribute(attributeName = "name")
	private String name;
	@DynamoDBAttribute(attributeName = "price")
	private int price;

	public String getPid() {
		return pid;
	}
	public void setPid(String pid) {
		this.pid = pid;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
       public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}

}

6. Create the service interface and its implementation class.

Service interface :

@Service
public interface ProductService {
Product readProduct(String pid);
}

Service interface Implementation :

@Service
public class ProductServiceImpl implements ProductService{
private ProductDao  productDao;
@Autowired
    public ProductServiceImpl(ProductDao productDao) {
        this.productDao = productDao;
    }
Logger logger = LoggerFactory.getLogger(ProductController.class);
@Override
public Product readProduct(String pid) {
// TODO Auto-generated method stub
logger.info("pid  ProductServiceImpl"+pid);
return productDao.readProduct(pid);
}

}

7. Create DAO interface and its implementation :

DAO interface

@Repository
public interface ProductDao {
public Product readProduct(String userId);
}

ProductDAOImpl.java

@Repository
public class ProductDAOImpl implements ProductDao {
Logger logger = LoggerFactory.getLogger(ProductController.class);
private DynamoDBMapper dynamoDBMapper;
@Autowired
public ProductDAOImpl(DynamoDBMapper dynamoDBMapper) {
this.dynamoDBMapper = dynamoDBMapper;
}
@Override
public Product readProduct(String pid) {
return dynamoDBMapper.load(Product.class, pid);
}
}

In the above DAO implementation class, we made the call to dynamoDBMapper load() method to query the date from Dynamo DB.

4. Possible Exceptions And Errors

1. AWS DynamoDB requested resource not found

Solutions:

  1. Verify if the AWS region properly updated on the DynamoDBConfiguration class. The region should be your AWS Account region.
  2. Check the table name because the table name is case sensitive.
  3. Have an eye on your AWS credentials

2. Parameter 0 of constructor in required a bean of type ‘java.Lang.String’ that could not be found

Solution:

Check all the spring components have been added with a proper annotation like @component,@service,@repository.

3. NULL pointer exception :

Check whether the dependency injection is done properly.

OUTPUT : To get the data from the Table product from DynamoDB hit the link http://localhost:8080/Product/1 in postman and you will get the data like the below image. Here we are passing the pid as path variable and get the data for the pid 1.

dynamoDB_output

CONCLUSION :

In this article, you learned about how to connect the DynamoDB table programmatically and read the data from it. Also if you want to update , write data into the table check the save, delete methods in the DynamoDBMapper class.