@@ -688,82 +688,56 @@ builder pattern.
688
688
689
689
690
690
691
+ ## Polymorphic Types Support
691
692
692
- ### Using subtypes to assist with single- table design
693
- It ' s considered a best practice in some situations to combine entities of various types into a single table in DynamoDb
694
- to enable the querying of multiple related entities without the need to actually join data across multiple tables. The
695
- enhanced client assists with this by supporting polymorphic mapping into distinct subtypes.
693
+ The Enhanced Client now supports ** polymorphic type hierarchies** , allowing multiple subclasses to be stored in the same table.
696
694
697
- Let ' s say you have a customer :
695
+ ### Usage Example : Person Hierarchy
698
696
699
697
```java
700
- public class Customer {
701
- String getCustomerId ();
702
- void setId (String id );
703
-
704
- String getName ();
705
- void setName (String name );
706
- }
707
- ```
708
-
709
- And an order that' s associated with a customer:
710
-
711
- ```java
712
- public class Order {
713
- String getOrderId();
714
- void setOrderId();
715
-
716
- String getCustomerId();
717
- void setCustomerId();
718
- }
719
- ```
720
-
721
- You could choose to store both of these in a single table that is indexed by customer ID, and create a TableSchema that
722
- is capable of mapping both types of entities into a common supertype:
723
-
724
- ```java
725
- import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
726
- import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
727
- import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSubtypeDiscriminator;
728
- import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSupertype;
729
- import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSupertype.Subtype;
730
-
731
698
@DynamoDbBean
732
- @DynamoDbSupertype({
733
- @Subtype(discriminatorValue = "CUSTOMER", subtypeClass = Customer.class),
734
- @Subtype(discriminatorValue = "ORDER", subtypeClass = Order.class)})
735
- public class CustomerRelatedEntity {
736
- @DynamoDbSubtypeDiscriminator
737
- String getEntityType();
738
- void setEntityType();
739
-
740
- @DynamoDbPartitionKey
741
- String getCustomerId();
742
- void setCustomerId();
743
- }
699
+ @DynamoDbSupertype (
700
+ value = {
701
+ @DynamoDbSupertype.Subtype (discriminatorValue = " EMPLOYEE" , subtypeClass = Employee . class),
702
+ @DynamoDbSupertype.Subtype (discriminatorValue = " CUSTOMER" , subtypeClass = Customer . class)
703
+ },
704
+ discriminatorAttributeName = " discriminatorType" // optional, defaults to "type"
705
+ )
706
+ public class Person {}
744
707
745
708
@DynamoDbBean
746
- public class Customer extends CustomerRelatedEntity {
747
- String getName();
748
- void setName(String name);
709
+ public class Employee extends Person {
710
+ private String employeeId;
711
+ public String getEmployeeId () { return employeeId; }
712
+ public void setEmployeeId (String id ) { this . employeeId = id; }
749
713
}
750
714
751
715
@DynamoDbBean
752
- public class Order extends CustomerRelatedEntity {
753
- String getOrderId();
754
- void setOrderId();
716
+ public class Customer extends Person {
717
+ private String customerId;
718
+ public String getCustomerId () { return customerId; }
719
+ public void setCustomerId (String id ) { this . customerId = id; }
755
720
}
756
721
```
757
722
758
- Now all you have to do is create a TableSchema that maps the supertype class:
723
+ ** Notes : **
724
+ - By default , the discriminator attribute is `" type" ` unless overridden.
725
+
726
+ ### Static / Immutable Schema Support
727
+
728
+ Polymorphism works for both ** bean- style** and ** immutable/ builder- based** classes.
729
+
759
730
```java
760
- TableSchema<CustomerRelatedEntity> tableSchema = TableSchema.fromClass(CustomerRelatedEntity.class);
761
- ```
762
- Now you have a `TableSchema` that can map any objects of both `Customer` and `Order` and write them to the table,
763
- and can also read any record from the table and correctly instantiate it using the subtype class. So it' s now possible
764
- to write a single query that will return both the customer record and all order records associated with a specific
765
- customer ID .
766
-
767
- As with all the other `TableSchema ` implementations, a static version is provided that allows reflective introspection
768
- to be skipped entirely and is recommended for applications where cold- start latency is critical. See the javadocs for
769
- `StaticPolymorphicTableSchema ` for an example of how to use this .
731
+ // Obtain schema for Person hierarchy
732
+ TableSchema<Person > schema = TableSchema . fromClass(Person . class);
733
+
734
+ // Serialize Employee → DynamoDB item
735
+ Employee e = new Employee ();
736
+ e. setEmployeeId(" E123" );
737
+ Map<String , AttributeValue > item = schema. itemToMap(e, false );
738
+ // → {"employeeId":"E123", "discriminatorType":"EMPLOYEE"}
739
+
740
+ // Deserialize back
741
+ Person restored = schema. mapToItem(item);
742
+ // → returns Employee instance
743
+ ```
0 commit comments