[英]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);
}
}
典型的類層次結構。 現在我正在嘗試使用公共存儲庫存儲AdminEventLogEntry
和UserEventLogEntry
:
@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.