Alterações nas APIs de mapeamento do DynamoDB entre a versão 1 e a versão 2 do SDK para Java - AWS SDK for Java 2.x

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Alterações nas APIs de mapeamento do DynamoDB entre a versão 1 e a versão 2 do SDK para Java

Criar um cliente

Caso de uso V1 V2

Instanciação normal

AmazonDynamoDB standardClient = AmazonDynamoDBClientBuilder.standard() .withCredentials(credentialsProvider) .withRegion(Regions.US_EAST_1) .build(); DynamoDBMapper mapper = new DynamoDBMapper(standardClient);
DynamoDbClient standardClient = DynamoDbClient.builder() .credentialsProvider(ProfileCredentialsProvider.create()) .region(Region.US_EAST_1) .build(); DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(standardClient) .build();

Instanciação mínima

AmazonDynamoDB standardClient = AmazonDynamoDBClientBuilder.standard(); DynamoDBMapper mapper = new DynamoDBMapper(standardClient);
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.create();

Com transformador de atributo*

DynamoDBMapper mapper = new DynamoDBMapper(standardClient, attributeTransformerInstance);
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(standardClient) .extensions(extensionAInstance, extensionBInstance) .build();

*As extensões na V2 correspondem aproximadamente aos transformadores de atributos na V1. A seção Usar extensões para personalizar as operações do Cliente Aprimorado do DynamoDB contém mais informações sobre extensões na V2.

Estabelecer o mapeamento para tabela/índice do DynamoDB

Na V1, você especifica um nome de tabela do DynamoDB por meio de uma anotação de bean. Na V2, um método de fábrica, table(), produz uma instância de DynamoDbTable que representa a tabela remota do DynamoDB. O primeiro parâmetro do método table() é o nome da tabela do DynamoDB.

Caso de uso V1 V2

Mapear a classe Java POJO para a tabela do DynamoDB

@DynamoDBTable(tableName ="Customer") public class Customer { ... }
DynamoDbTable<Customer> customerTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));

Mapear para um índice secundário do DynamoDB

  1. Defina uma classe POJO que represente o índice.

    • Anote a classe com @DynamoDBTable fornecendo o nome da tabela que tem o índice.

    • Anote as propriedades com @DynamoDBIndexHashKey e, opcionalmente, @DynamoDBIndexRangeKey.

  2. Crie uma expressão de consulta.

  3. Consulte usando referência à classe POJO que representa o índice. Por exemplo

    mapper.query(IdEmailIndex.class, queryExpression)

    onde IdEmailIndex é a classe de mapeamento para o índice.

A seção do Guia do desenvolvedor do DynamoDB que discute o método query da V1 mostra um exemplo completo.

  1. Anote os atributos de uma classe POJO com @DynamoDbSecondaryPartitionKey (para um GSI) e @DynamoDbSecondarySortKey (para e GSI ou LSI). Por exemplo,

    @DynamoDbSecondarySortKey(indexNames = "IdEmailIndex") public String getEmail() { return this.email; }
  2. Recupere uma referência ao índice. Por exemplo,

    DynamoDbIndex<Customer> customerIndex = customerTable.index("IdEmailIndex");
  3. Consulte o índice.

A seção Usar índices secundários deste guia fornece mais informações.

Operações de tabela

Esta seção descreve as APIs de operação que diferem entre V1 e V2 na maioria dos casos de uso padrão.

Na V2, todas as operações que envolvem uma única tabela são chamadas na instância DynamoDbTable, não no cliente aprimorado. O cliente aprimorado contém métodos que podem ter como destino várias tabelas.

Na tabela chamada Operações de tabela abaixo, uma instância POJO é chamada de item ou como um tipo específico, como customer1. Para os exemplos da V2 de as instâncias nomeadas, table é o resultado de uma chamada anterior a enhancedClient.table() que retorna uma referência à instância DynamoDbTable.

Observe que a maioria das operações da V2 pode ser chamada com um padrão de consumidor fluente, mesmo quando não mostrado. Por exemplo,

Customer customer = table.getItem(r → r.key(key)); or Customer customer = table.getItem(r → r.key(k -> k.partitionValue("id").sortValue("email")))

Para operações da V1, as Operações de tabela (abaixo) contêm algumas das formas mais usadas, mas não todas as formas com sobrecargas. Por exemplo, o método load() tem as seguintes sobrecargas:

mapper.load(Customer.class, hashKey) mapper.load(Customer.class, hashKey, rangeKey) mapper.load(Customer.class, hashKey, config) mapper.load(Customer.class, hashKey, rangeKey, config) mapper.load(item) mapper.load(item, config)

As Operações de tabela (abaixo) mostram as formas comumente usados:

mapper.load(item) mapper.load(item, config)
Operações de tabela
Caso de uso V1 V2

Gravar um Java POJO em uma tabela do DynamoDB

Operação do DynamoDB: PutItem, UpdateItem

mapper.save(item) mapper.save(item, config) mapper.save(item, saveExpression, config)

Na V1, DynamoDBMapperConfig.SaveBehavior e anotações determinam qual método de baixo nível do DynamoDB será chamado. Em geral, UpdateItem é chamado, exceto quando se usa SaveBehavior.CLOBBER e SaveBehavior.PUT. As chaves geradas automaticamente são um caso de uso especial e, ocasionalmente, tanto PutItem como UpdateItem são usadas.

table.putItem(putItemRequest) table.putItem(item) table.putItemWithResponse(item) //Returns metadata. updateItem(updateItemRequest) table.updateItem(item) table.updateItemWithResponse(item) //Returns metadata.

Ler um item de uma tabela do DynamoDB para um Java POJO

Operação do DynamoDB: GetItem

mapper.load(item) mapper.load(item, config)
table.getItem(getItemRequest) table.getItem(item) table.getItem(key) table.getItemWithResponse(key) //Returns POJO with metadata.

Excluir um item de uma tabela do DynamoDB

Operação do DynamoDB: DeleteItem

mapper.delete(item, deleteExpression, config)
table.deleteItem(deleteItemRequest) table.deleteItem(item) table.deleteItem(key)

Consultar uma tabela ou um índice secundário do DynamoDB e retornar uma lista paginada

Operação do DynamoDB: Query

mapper.query(Customer.class, queryExpression) mapper.query(Customer.class, queryExpression, mapperConfig)
table.query(queryRequest) table.query(queryConditional)

Usar o PageIterable.stream() retornado (carregamento lento) para respostas sincronizadas e PagePublisher.subscribe() para respostas assíncronas

Consultar uma tabela ou um índice secundário do DynamoDB e retornar uma lista

Operação do DynamoDB: Query

mapper.queryPage(Customer.class, queryExpression) mapper.queryPage(Customer.class, queryExpression, mapperConfig)
table.query(queryRequest) table.query(queryConditional)

Usar o PageIterable.items() retornado (carregamento lento) para respostas sincronizadas e PagePublisher.items.subscribe() para respostas assíncronas

Verificar uma tabela ou um índice secundário do DynamoDB e retornar uma lista paginada

Operação do DynamoDB: Scan

mapper.scan(Customer.class, scanExpression) mapper.scan(Customer.class, scanExpression, mapperConfig)
table.scan() table.scan(scanRequest)

Usar o PageIterable.stream() retornado (carregamento lento) para respostas sincronizadas e PagePublisher.subscribe() para respostas assíncronas

Fazer uma varredura de uma tabela ou um índice secundário do DynamoDB e retornar uma lista

Operação do DynamoDB: Scan

mapper.scanPage(Customer.class, scanExpression) mapper.scanPage(Customer.class, scanExpression, mapperConfig)
table.scan() table.scan(scanRequest)

Usar o PageIterable.items() retornado (carregamento lento) para respostas sincronizadas e PagePublisher.items.subscribe() para respostas assíncronas

Ler vários itens de várias tabelas em um lote

Operação do DynamoDB: BatchGetItem

mapper.batchLoad(Arrays.asList(customer1, customer2, book1)) mapper.batchLoad(itemsToGet) // itemsToGet: Map<Class<?>, List<KeyPair>>
enhancedClient.batchGetItem(batchGetItemRequest) enhancedClient.batchGetItem(r -> r.readBatches( ReadBatch.builder(Record1.class) .mappedTableResource(mappedTable1) .addGetItem(i -> i.key(k -> k.partitionValue(0))) .build(), ReadBatch.builder(Record2.class) .mappedTableResource(mappedTable2) .addGetItem(i -> i.key(k -> k.partitionValue(0))) .build())) // Iterate over pages with lazy loading or over all items from the same table.

Gravar vários itens em várias tabelas em um lote

Operação do DynamoDB: BatchWriteItem

mapper.batchSave(Arrays.asList(customer1, customer2, book1))
enhancedClient.batchWriteItem(batchWriteItemRequest) enhancedClient.batchWriteItem(r -> r.writeBatches( WriteBatch.builder(Record1.class) .mappedTableResource(mappedTable1) .addPutItem(item1) .build(), WriteBatch.builder(Record2.class) .mappedTableResource(mappedTable2) .addPutItem(item2) .build()))

Excluir vários itens de várias tabelas em um lote

Operação do DynamoDB: BatchWriteItem

mapper.batchDelete(Arrays.asList(customer1, customer2, book1))
enhancedClient.batchWriteItem(r -> r.writeBatches( WriteBatch.builder(Record1.class) .mappedTableResource(mappedTable1) .addDeleteItem(item1key) .build(), WriteBatch.builder(Record2.class) .mappedTableResource(mappedTable2) .addDeleteItem(item2key) .build()))

Gravar/excluir vários itens em um lote

Operação do DynamoDB: BatchWriteItem

mapper.batchWrite(Arrays.asList(customer1, book1), Arrays.asList(customer2))
enhancedClient.batchWriteItem(r -> r.writeBatches( WriteBatch.builder(Record1.class) .mappedTableResource(mappedTable1) .addPutItem(item1) .build(), WriteBatch.builder(Record2.class) .mappedTableResource(mappedTable2) .addDeleteItem(item2key) .build()))

Fazer uma gravação transacional

Operação do DynamoDB: TransactWriteItems

mapper.transactionWrite(transactionWriteRequest)
enhancedClient.transactWriteItems(transasctWriteItemsRequest)

Fazer uma leitura transacional

Operação do DynamoDB: TransactGetItems

mapper.transactionLoad(transactionLoadRequest)
enhancedClient.transactGetItems(transactGetItemsRequest)

Obter uma contagem de itens correspondentes de uma consulta

Operação do DynamoDB: Query com Select.COUNT

mapper.count(Customer.class, queryExpression)
// Get the count from query results. PageIterable<Customer> pageIterable = customerTable.query(QueryEnhancedRequest.builder() .queryConditional(queryConditional) .select(Select.COUNT) .build()); Iterator<Page<Customer>> iterator = pageIterable.iterator(); Page<Customer> page = iterator.next(); int count = page.count(); // For a more concise approach, you can chain the method calls: int count = customerTable.query(QueryEnhancedRequest.builder() .queryConditional(queryConditional) .select(Select.COUNT) .build()) .iterator().next().count();

Obter uma contagem de itens correspondentes de uma varredura

Operação do DynamoDB: Scan com Select.COUNT

mapper.count(Customer.class, scanExpression)
// Get the count from scan results. PageIterable<Customer> pageIterable = customerTable.scan(ScanEnhancedRequest.builder() .filterExpression(filterExpression) .select(Select.COUNT) .build()); Iterator<Page<Customer>> iterator = pageIterable.iterator(); Page<Customer> page = iterator.next(); int count = page.count(); // For a more concise approach, you can chain the method calls: int count = customerTable.scan(ScanEnhancedRequest.builder() .filterExpression(filterExpression) .select(Select.COUNT) .build()) .iterator().next().count();

Criar uma tabela no DynamoDB correspondente à classe POJO

Operação do DynamoDB: CreateTable

mapper.generateCreateTableRequest(Customer.class)

A declaração anterior gera uma solicitação de criação de tabela de baixo nível; os usuários devem chamar createTable no cliente do DynamoDB.

table.createTable(createTableRequest) table.createTable(r -> r.provisionedThroughput(defaultThroughput()) .globalSecondaryIndices( EnhancedGlobalSecondaryIndex.builder() .indexName("gsi_1") .projection(p -> p.projectionType(ProjectionType.ALL)) .provisionedThroughput(defaultThroughput()) .build()));

Fazer uma varredura paralela no DynamoDB

Operação do DynamoDB: Scan com parâmetros Segment e TotalSegments

mapper.parallelScan(Customer.class, scanExpression, numTotalSegments)

Os usuários devem gerenciar as threads de operador e chamar scan para cada segmento:

table.scan(r -> r.segment(0).totalSegments(5))

Integrar o Amazon S3 com o DynamoDB para armazenar links inteligentes do S3

mapper.createS3Link(bucket, key) mapper.getS3ClientCache()

Incompatível porque combina o Amazon S3 e o DynamoDB.

Classes e propriedades de mapa

Tanto na V1 quanto na V2, você mapeia classes para tabelas usando anotações no estilo bean. A V2 também oferece outras formas de definir esquemas para casos de uso específicos, como trabalhar com classes imutáveis.

Anotações de bean

A tabela a seguir mostra as anotações de bean equivalentes para um caso de uso específico que são usadas na V1 e na V2. Um cenário de classe Customer é usado para ilustrar os parâmetros.

As anotações, assim como as classes e enumerações, na V2 seguem a convenção de casos camel e usam “DynamoDb”, não “DynamoDB”.

Caso de uso V1 V2
Mapear classe para tabela
@DynamoDBTable (tableName ="CustomerTable")
@DynamoDbBean @DynamoDbBean(converterProviders = {...})
O nome da tabela é definido ao chamar o método DynamoDbEnhancedClient#table().
Designar um membro da classe como um atributo da tabela
@DynamoDBAttribute(attributeName = "customerName")
@DynamoDbAttribute("customerName")
Designar um membro da classe é uma chave de partição/hash
@DynamoDBHashKey
@DynamoDbPartitionKey
Designar um membro da classe é uma chave de classificação/intervalo
@DynamoDBRangeKey
@DynamoDbSortKey
Designar um membro da classe é uma chave de partição/hash de índice secundário
@DynamoDBIndexHashKey
@DynamoDbSecondaryPartitionKey
Designar um membro da classe é uma chave de classificação/intervalo de índice secundário
@DynamoDBIndexRangeKey
@DynamoDbSecondarySortKey
Ignorar esse membro da classe ao mapear para uma tabela
@DynamoDBIgnore
@DynamoDbIgnore
Designar um membro da classe como um atributo de chave UUID gerado automaticamente
@DynamoDBAutoGeneratedKey
@DynamoDbAutoGeneratedUuid

A extensão que fornece isso não é carregada por padrão; você deve adicionar a extensão ao compilador de cliente.

Designar um membro da classe como um atributo de carimbo de data e hora gerado automaticamente
@DynamoDBAutoGeneratedTimestamp
@DynamoDbAutoGeneratedTimestampAttribute

A extensão que fornece isso não é carregada por padrão; você deve adicionar a extensão ao compilador de cliente.

Designar um membro da classe como um atributo de versão incrementado automaticamente
@DynamoDBVersionAttribute
@DynamoDbVersionAttribute

A extensão que fornece isso é carregada automaticamente.

Designar um membro da classe como solicitando uma conversão personalizada
@DynamoDBTypeConverted
@DynamoDbConvertedBy
Designar um membro da classe para ser armazenado como um tipo de atributo diferente
@DynamoDBTyped(<DynamoDBAttributeType>)

Use uma implementação AttributeConverter. A V2 fornece muitos conversores incorporados para tipos de Java comuns. Você também pode implementar seu próprio AttributeConverter ou AttributeConverterProvider personalizado. Veja Conversão de atributo de controle neste guia.

Designar uma classe que possa ser serializada em um documento do DynamoDB (documento no estilo JSON) ou subdocumento
@DynamoDBDocument
Use a API de documento aprimorado. Consulte os recursos a seguir:

Anotações adicionais da V2

Caso de uso V1 V2
Designar um membro da classe para não ser armazenado como um atributo NULL se o valor Java for nulo N/D
@DynamoDbIgnoreNulls
Designar um membro da classe para ser um objeto vazio se todos os atributos forem nulos N/D
@DynamoDbPreserveEmptyObject
Designar uma ação especial de atualização para um membro da classe N/D
@DynamoDbUpdateBehavior
Designar uma classe imutável N/D
@DynamoDbImmutable
Designar um membro da classe como um atributo de contador incrementado automaticamente N/D
@DynamoDbAtomicCounter

A extensão que fornece essa funcionalidade é carregada automaticamente.

Configuração

Na V1, você geralmente controla comportamentos específicos usando uma instância de DynamoDBMapperConfig. Você pode fornecer o objeto de configuração ao criar o mapeador ou ao fazer uma solicitação. Na V2, a configuração é específica para o objeto de solicitação da operação.

Caso de uso V1 Padrão na V1 V2
DynamoDBMapperConfig.builder()
Estratégia de nova tentativa de carregamento/gravação em lote
.withBatchLoadRetryStrategy(loadRetryStrategy)
.withBatchWriteRetryStrategy(writeRetryStrategy)
fazer novas tentativas de itens com falha Configure a estratégia de novas tentativas no DynamoDBClient subjacente. Veja Configurar o comportamento de novas tentativas no AWS SDK for Java 2.x neste guia.
Leituras consistentes
.withConsistentReads(CONSISTENT)
EVENTUAL Por padrão, leituras consistentes são falsas para operações de leitura. Substitua por .consistentRead(true) no objeto de solicitação.
Esquema de conversão com conjuntos de marshallers/unmarshallers
.withConversionSchema(conversionSchema)

As implementações estáticas fornecem compatibilidade retroativa com versões mais antigas.

V2_COMPATIBLE Não aplicável. Esse é um recurso legado que se refere à forma como as versões mais antigas do DynamoDB (V1) armazenavam os tipos de dados, e esse comportamento não será preservado no cliente aprimorado. Um exemplo de comportamento no DynamoDB V1 é armazenar boolianos como número em vez de boolianos.
Nomes das tabelas
.withObjectTableNameResolver() .withTableNameOverride() .withTableNameResolver()

As implementações estáticas fornecem compatibilidade retroativa com versões mais antigas

usar anotação ou suposição da classe

O nome da tabela é definido ao chamar o método DynamoDbEnhancedClient#table().

Estratégia de carregamento de paginação
.withPaginationLoadingStrategy(strategy)

As opções são: LAZY_LOADING, EAGER_LOADING ou ITERATION_ONLY

LAZY_LOADING
  • Somente a iteração é o padrão. As outras opções da V1 não são compatíveis.

  • Você pode implementar o equivalente ao carregamento antecipado (eager) na V2 com o seguinte:

    List<Customer> allItems = customerTable.scan().items().stream().collect(Collectors.toList());
  • Para carregamento sob demanda (lazy), você deve implementar sua própria lógica de armazenamento em cache para itens acessados.

Solicitar coleta de métricas
.withRequestMetricCollector(collector)
null Use metricPublisher() em ClientOverrideConfiguration ao criar o cliente padrão do DynamoDB.
Comportamento de salvamento
.withSaveBehavior(SaveBehavior.CLOBBER)

As opções são UPDATE, CLOBBER, PUT, APPEND_SET ou UPDATE_SKIP_NULL_ATTRIBUTES.

UPDATE

Na V2, você chama putItem() ou updateItem() explicitamente.

CLOBBER or PUT: a ação correspondente na v2 está chamando putItem(). Não há configuração CLOBBER específica.

UPDATE: Corresponde a updateItem()

UPDATE_SKIP_NULL_ATTRIBUTES: Corresponde a updateItem(). Controle o comportamento da atualização com a configuração da solicitação ignoreNulls e a anotação/tag DynamoDbUpdateBehavior.

APPEND_SET: incompatível

Fábrica de conversão de tipo
.withTypeConverterFactory(typeConverterFactory)
conversores de tipo padrão

Definir o bean usando

@DynamoDbBean(converterProviders = {ConverterProvider.class, DefaultAttributeConverterProvider.class})

Configuração por operação

Na V1, algumas operações, como query(), são altamente configuráveis por meio de um objeto de “expressão” enviado à operação. Por exemplo:

DynamoDBQueryExpression<Customer> emailBwQueryExpr = new DynamoDBQueryExpression<Customer>() .withRangeKeyCondition("Email", new Condition() .withComparisonOperator(ComparisonOperator.BEGINS_WITH) .withAttributeValueList( new AttributeValue().withS("my"))); mapper.query(Customer.class, emailBwQueryExpr);

Na V2, em vez de usar um objeto de configuração, você define parâmetros no objeto de solicitação usando um compilador. Por exemplo:

QueryEnhancedRequest emailBw = QueryEnhancedRequest.builder() .queryConditional(QueryConditional .sortBeginsWith(kb -> kb .sortValue("my"))).build(); customerTable.query(emailBw);

Condicionais

Na V2, as expressões condicionais e de filtragem são expressas usando um objeto Expression, que encapsula a condição e o mapeamento de nomes e filtros.

Caso de uso Operações V1 V2
Condições de atributo esperadas save(), delete(), query(), scan()
new DynamoDBSaveExpression() .withExpected(Collections.singletonMap( "otherAttribute", new ExpectedAttributeValue(false))) .withConditionalOperator(ConditionalOperator.AND);
Obsoleto; use ConditionExpression em vez disso.
Expressão de condição delete()
deleteExpression.setConditionExpression("zipcode = :zipcode") deleteExpression.setExpressionAttributeValues(...)
Expression conditionExpression = Expression.builder() .expression("#key = :value OR #key1 = :value1") .putExpressionName("#key", "attribute") .putExpressionName("#key1", "attribute3") .putExpressionValue(":value", AttributeValues.stringValue("wrong")) .putExpressionValue(":value1", AttributeValues.stringValue("three")) .build(); DeleteItemEnhancedRequest request = DeleteItemEnhancedRequest.builder() .conditionExpression(conditionExpression).build();
Expressão de filtro query(), scan()
scanExpression .withFilterExpression("#statename = :state") .withExpressionAttributeValues(attributeValueMapBuilder.build()) .withExpressionAttributeNames(attributeNameMapBuilder.build())
Map<String, AttributeValue> values = singletonMap(":key", stringValue("value")); Expression filterExpression = Expression.builder() .expression("name = :key") .expressionValues(values) .build(); QueryEnhancedRequest request = QueryEnhancedRequest.builder() .filterExpression(filterExpression).build();
Expressão de condição para consulta query()
queryExpression.withKeyConditionExpression()
QueryConditional keyEqual = QueryConditional.keyEqualTo(b -> b .partitionValue("movie01")); QueryEnhancedRequest tableQuery = QueryEnhancedRequest.builder() .queryConditional(keyEqual) .build();

Conversão de tipo

Conversores padrão

Na V2, o SDK fornece um conjunto de conversores padrão para todos os tipos comuns. É possível alterar os conversores de tipo tanto no nível geral do provedor quanto em um único atributo. Você pode encontrar uma lista dos conversores disponíveis na referência da API AttributeConverter.

Definir um conversor personalizado para um atributo

Na V1, é possível e anotar um método getter com @DynamoDBTypeConverted para especificar a classe que é convertida entre o tipo de atributo Java e o tipo de atributo do DynamoDB. Por exemplo, um CurrencyFormatConverter que converte entre um tipo Java Currency e uma string do DynamoDB pode ser aplicada conforme mostrado no trecho a seguir.

@DynamoDBTypeConverted(converter = CurrencyFormatConverter.class) public Currency getCurrency() { return currency; }

O equivalente da V2 do trecho anterior é mostrado abaixo.

@DynamoDbConvertedBy(CurrencyFormatConverter.class) public Currency getCurrency() { return currency; }
nota

Na V1, é possível aplicar a anotação ao próprio atributo, a um tipo ou a uma anotação definida pelo usuário. A V2 permite a aplicação da anotação somente ao getter.

Adicionar uma fábrica ou fornecedor de conversor de tipo

Na V1, você pode fornecer seu próprio conjunto de conversores de tipo, ou substituir os tipos que forem importantes para você adicionando uma fábrica de conversores de tipo à configuração. A fábrica do conversor de tipos amplia DynamoDBTypeConverterFactory e as substituições são feitas obtendo uma referência ao conjunto padrão e ampliando-o. O trecho a seguir demonstra como fazer isso.

DynamoDBTypeConverterFactory typeConverterFactory = DynamoDBTypeConverterFactory.standard().override() .with(String.class, CustomBoolean.class, new DynamoDBTypeConverter<String, CustomBoolean>() { @Override public String convert(CustomBoolean bool) { return String.valueOf(bool.getValue()); } @Override public CustomBoolean unconvert(String string) { return new CustomBoolean(Boolean.valueOf(string)); }}).build(); DynamoDBMapperConfig config = DynamoDBMapperConfig.builder() .withTypeConverterFactory(typeConverterFactory) .build(); DynamoDBMapper mapperWithTypeConverterFactory = new DynamoDBMapper(dynamo, config);

A V2 fornece funcionalidade semelhante por meio da anotação @DynamoDbBean. Você pode fornecer um único AttributeConverterProvider ou uma cadeia de AttributeConverterProviders ordenados. Observe que, se fornecer sua própria cadeia de provedores de conversão de atributos, você substituirá o provedor de conversão padrão, e deve incluí-lo na cadeia para usar os conversores de atributos.

@DynamoDbBean(converterProviders = { ConverterProvider1.class, ConverterProvider2.class, DefaultAttributeConverterProvider.class}) public class Customer { ... }

A seção sobre conversão de atributos neste guia contém um exemplo completo para a V2.