簡體   English   中英

Amazon DynamoDB和類層次結構

[英]Amazon DynamoDB and class hierarchy

我使用這個庫使用Spring Boot和Amazon DynamoDB。 問題出在這個類層次結構中:

@DynamoDBTable(tableName = "EventLogs")
abstract class AbstractEventLogEntry implements Serializable {
  private static final long serialVersionUID = 7713867887326010287L;

  @DynamoDBHashKey(attributeName = "EventId")
  private String eventId;

  @DynamoDBAttribute(attributeName = "GeneratedAt")
  @DynamoDBMarshalling(marshallerClass = ZonedDateTimeMarshaller.class)
  private ZonedDateTime generatedAt;

  AbstractEventLogEntry() {
    eventId = new UUID().value();
    generatedAt = ZonedDateTime.now();
  }

  /* Getters / Setter */
}

......另一堂課:

public abstract class EventLogEntry extends AbstractEventLogEntry {
  private static final long serialVersionUID = 1638093418868197192L;

  @DynamoDBAttribute(attributeName = "UserId")
  private String userId;

  @DynamoDBAttribute(attributeName = "EventName")
  private String eventName;

  protected EventLogEntry(AdminEvent event) {
    userId = event.getUserName();
    eventName = event.getClass().getSimpleName();
  }

  protected EventLogEntry(UserEvent event) {
    userId = event.getUserId();
    eventName = event.getClass().getSimpleName();
  }

  /* Getters / Setter */
}

...另一個:

public class AdminEventLogEntry extends EventLogEntry {
  private static final long serialVersionUID = 1953428576998278984L;

  public AdminEventLogEntry(AdminEvent event) {
    super(event);
  }
}

......最后一個:

public class UserEventLogEntry extends EventLogEntry {
  private static final long serialVersionUID = 6845335344191463717L;

  public UserEventLogEntry(UserEvent event) {
    super(event);
  }
}

典型的類層次結構。 現在我正在嘗試使用公共存儲庫存儲AdminEventLogEntryUserEventLogEntry

@EnableScan
public interface EventLogEntryRepository extends DynamoDBCrudRepository<EventLogEntry, String> {
  // ...
}

......它總是告訴我:

com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException: no key(s) present on class io.shido.events.domain.AdminEventLogEntry

一旦我再次聲明其工作的密鑰:

@DynamoDBHashKey(attributeName = "EventId")
private String eventId;

所以我的問題是:我是否需要重新聲明層次結構之間可能常見的所有字段? 它看起來好像沒有從父母HashKey識別出HashKey

有線索嗎?

我找到了解決方案(前一段時間),所以我正在更新帖子以防將來有人需要它。 注意abstract類不再存在,也許你可以為自己的目的調整它,我沒有時間來測試它(現在不是......所以它更簡單,從OOP的角度來看可能不完全正確)。

問題在於類層次結構和(基於Spring的)AmazonDB客戶端的配置。 接下來的課程是實際的解決方案。

(a)Amazon DynamoDB客戶端的Spring配置文件。

請注意,您可能不需要dynamoDBOperationsRef因為它僅用於“每個環境”需要不同表的情況。 使用DynamoDB(如果您只有一個帳戶),您不能擁有不同的“環境”,因此您必須找到解決方法。 這是解決方案:為表添加前綴(並根據需要應用安全設置)。

@Configuration
@EnableContextInstanceData // Only if you are going to use Identity and Access Management (IAM)
@EnableDynamoDBRepositories(basePackages = "io.shido.events", dynamoDBOperationsRef = "dynamoDBOperations")
class AmazonConfiguration {
  @Value("${aws.endpoint.dynamodb}")
  private String dynamoDbEndpoint;

  @Value("${ENV:local}")
  private String environment;

  @Bean
  public AmazonDynamoDB amazonDynamoDB() {
    final AmazonDynamoDBClient client = new AmazonDynamoDBClient();
    //client.setSignerRegionOverride(Regions.fromName(region).getName());
    if (StringUtils.isNotEmpty(dynamoDbEndpoint)) {
      client.setEndpoint(dynamoDbEndpoint);
    }
    return client;
  }

  @Bean
  public DynamoDBOperations dynamoDBOperations() {
    final DynamoDBTemplate template = new DynamoDBTemplate(amazonDynamoDB());
    final DynamoDBMapperConfig mapperConfig = DynamoDBMapperConfig.builder()
      .withTableNameOverride(DynamoDBMapperConfig.TableNameOverride.withTableNamePrefix(environment + "-"))
      .build();
    template.setDynamoDBMapperConfig(mapperConfig);
    return template;
  }
}

(b)DynamoDB注釋“實體”類

package io.shido.events;

// imports

@DynamoDBTable(tableName = "EventLogs")
final class EventLogEntry implements Serializable {
  // Define your own long serialVersionUID

  @DynamoDBHashKey(attributeName = "EventId")
  private String eventId;

  @DynamoDBTypeConvertedEnum
  @DynamoDBAttribute(attributeName = "EventType")
  private EventType type;

  @DynamoDBAttribute(attributeName = "EntityId")
  private String entityId;

  @Scrambled
  @DynamoDBAttribute(attributeName = "Event")
  private Event event;

  @DynamoDBAttribute(attributeName = "GeneratedAt")
  @DynamoDBTypeConverted(converter = ZonedDateTimeConverter.class)
  private ZonedDateTime generatedAt;

  public EventLogEntry() {
    generatedAt = ZonedDateTime.now();
  }

  public EventLogEntry(AdminEvent event) {
    this();
    eventId = event.getId();
    type = EventType.ADMIN;
    entityId = event.getEntityId();
    this.event = event;
  }

  public EventLogEntry(UserEvent event) {
    this();
    eventId = event.getId();
    type = EventType.USER;
    entityId = event.getEntityId();
    this.event = event;
  }

  // getters and setters (a MUST, at least till the version I'm using)

  // hashCode(), equals and toString()
}

(c)Spring存儲庫定義。

@EnableScan
public interface EventLogEntryRepository extends DynamoDBCrudRepository<EventLogEntry, String> { }

(d)表格定義。

最終,您定義屬性和方式的方式取決於您和/或您的要求。

{
  "TableName" : "local-EventLogs",
  "AttributeDefinitions" : [
    { "AttributeName" : "EventId", "AttributeType" : "S" },
    { "AttributeName" : "EventType", "AttributeType" : "S" },
    { "AttributeName" : "EntityId", "AttributeType" : "S" },
    { "AttributeName" : "Event", "AttributeType" : "S" },
    { "AttributeName" : "GeneratedAt", "AttributeType" : "S" }
  ],
  "KeySchema" : [ { "AttributeName" : "EventId", "KeyType" : "HASH" } ],
  "ProvisionedThroughput" : { "ReadCapacityUnits" : 10, "WriteCapacityUnits" : 10 }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM