javaspringspring-bootamazon-dynamodbamazon-dynamodb-data-modeling

Java DynamoDB: Add Items without Declaring Fields in an Entity Class


The following example will map and adds Items into a DynamoDB Table. I thought the purpose of NoSQL is allow fields without specifying the Structure/types in a data structure entity.

How can I add fields into DynamoDB without specifying actual EntityType? (in this case, "Person" Entity class). Prefer to setup Postman to allow random Json elements .

I want to add any field in this Json, which are not in the Entity class. For example, "StreetAddress", "Car", "phoneNumber",

DynamoDBConfig

@RequiredArgsConstructor
@Configuration
public class DynamoDbConfig {

    @Bean
    public DynamoDBMapperConfig dynamoDBMapperConfig() {
        return DynamoDBMapperConfig.DEFAULT;
    }

    @Bean
    public DynamoDBMapper mapper() {
        return new DynamoDBMapper(amazonDynamoDBConfig());
    }

    @Bean
    public AmazonDynamoDB amazonDynamoDBConfig() {
        return AmazonDynamoDBClientBuilder.standard()
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("dynamodb.us-west-2.amazonaws.com", "us-west-2"))
                .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("TestExample", "ExampleExample")))
                .build();
    }
}

Entity

@Data
@AllArgsConstructor
@NoArgsConstructor
@DynamoDBTable(tableName="person")
public class Person implements Serializable {
    @DynamoDBHashKey(attributeName = "personId")
    @DynamoDBAutoGeneratedKey
    private String personId;

    @DynamoDBAttribute
    private String name;

    @DynamoDBAttribute
    private int age;

    @DynamoDBAttribute
    private String email;
}

Controller:

@RestController
@RequestMapping("/api")
@CrossOrigin
public class PersonController {
    private PersonRepository repository;

    @Autowired
    public PersonController(PersonRepository repository) {
        this.repository = repository;
    }

    @PostMapping("/savePerson")
    public Person savePerson(@RequestBody Person person) {
        return repository.addPerson(person);
    }
}

Repository:

@Repository
public class PersonRepository {
    private DynamoDBMapper mapper;

    @Autowired
    public PersonRepository(DynamoDBMapper mapper) {
        this.mapper = mapper;
    }

    public Person addPerson(Person person) {
        mapper.save(person);
        return person;
    }
}

Test in Postman:

I want to add any field in this Json, which are not in the Entity class. For example, StreetAddress, Car, phoneNumber,

enter image description here


Solution

  • You can insert values into table by dynamic AttributeValue

    import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
    import com.amazonaws.services.dynamodbv2.model.AttributeValue;
    
    
    @Service
    public class DynamoService {
    
        @Autowired AmazonDynamoDB amazonDynamoClient;
    
        public void putItemByMap(String nameTable, Map<String,String> values){
    
            Map<String,AttributeValue> mapValuesToBePut = 
                   values.entrySet()
                         .stream()
                         .collect(Collectors.toMap(
                            Map.Entry::getKey, entry -> new AttributeValue(entry.getValue()))
                          );
    
            amazonDynamoClient.putItem(nameTable, mapValuesToBePut);
        }
    }