首页 > 解决方案 > Spring Boot 应用程序中的 Spring-data-dynamoDB:如果配置了 @EnableDynamoDBAuditing,则 @DynamoDBTable 类不会被识别为持久实体

问题描述

我正在尝试向现有的 Spring Boot/Spring Data JPA 应用程序添加对 DynamoDB 的支持 - 使用spring-data-dynamodb

我希望能够使用互斥的 Spring 配置文件(jpadynamodb。)在 JPA(Oracle、HSQL)和 DynamoDB 之间切换。所以我有两个特定于配置文件的@Configuration类:

@Configuration
@Profile("jpa")
@SpringBootConfiguration
@EnableAutoConfiguration
@EnableJpaRepositories(basePackages = "my.persistence.repositories")
@EnableJpaAuditing
public class JpaConfig {
}

@Configuration
@Profile("dynamodb")
@EnableDynamoDBRepositories(basePackages = "my.persistence.repositories")
@EnableDynamoDBAuditing
@EnableAutoConfiguration(exclude = {
    DataSourceTransactionManagerAutoConfiguration.class,
    DataSourceAutoConfiguration.class,
    HibernateJpaAutoConfiguration.class
})
@ConfigurationProperties(prefix = "amazon.aws")
@Setter
public class DynamoDBConfig {

    private String dynamoDbEndpoint;
    private String accessKey;
    private String secretKey;
    private String region;

    @Bean
    public AmazonDynamoDB amazonDynamoDB() {
        Assert.hasText(dynamoDbEndpoint, "AWS DynamoDB endpoint is not configured!");
        Assert.hasText(region, "AWS sign-in region must be explicitly configured!");
        AmazonDynamoDBClientBuilder builder = AmazonDynamoDBClientBuilder.standard()
            .withCredentials(new AWSStaticCredentialsProvider(amazonAWSCredentials()));
        builder.setEndpointConfiguration(
                  new AwsClientBuilder.EndpointConfiguration(dynamoDbEndpoint, region));
        return builder.build();
    }

    @Bean
    public AWSCredentials amazonAWSCredentials() {
        return new BasicAWSCredentials(accessKey, secretKey);
    }
}

}

该类Application@Configuration和注释@ComponentScan

请注意,我特别尝试在dynamodb激活配置文件时排除任何 JPA 自动配置。对于 DynamoDB,我想通过启用审计EnableDynamoDBAuditing- 我假设它是spring-data-dynamodbSpring Data JPA 的等价物EnableJpaAuditing,尽管我找不到任何明确的文档,Javadoc 什么也没提供。

我希望能够使用相同的 Spring Data 存储库接口和实体类。当然,存储库接口中没有特定于 JPA 或 DynamoDB 的内容。而且我认为将 DynamoDb 注释添加到现有的 JPA 注释不应该有任何伤害。所以我有如下实体类(一个旧的 JPA 实体类,添加了 DynamoDB 注释):

 @Entity
 @Table(name = "person")
 @DynamoDBTable(tableName = "person")
 @EntityListeners({AuditingEntityListener.class})
 @Getter
 @Setter
 @NoArgsConstructor
 @ToString
 public class Person implements Serializable {
     private static final long serialVersionUID = 1L;

     @Id
     @DynamoDBHashKey
     @DynamoDBAutoGeneratedKey
     private String id;

     @Column(name = "first_name")
     @DynamoDBAttribute
     private String firstName;

     @Column(name = "last_name")
     @DynamoDBAttribute
     private String lastName;

     @Column(name = "created_dt", nullable = false)
     @CreatedDate
     @DynamoDBAttribute
     @DynamoDBAutoGeneratedTimestamp(strategy=DynamoDBAutoGenerateStrategy.CREATE)
     private Date createdDate;

     ... etc.
}

并且相应的存储库保持不变(我只添加了@EnableScan注释,如下示例):

 @EnableScan
 public interface PersonRepository extends Repository<Person, String> {

      Person findOne(String id);

      Person save(Person person);
 }

当我在jpa激活 Spring 配置文件的情况下运行应用程序时,一切正常 - 就像在添加 DynamoDB 支持之前一样。但是,当我使用dynamodb配置文件启动应用程序时,它启动正常,但数据访问操作失败,并出现异常,表明 Person 对象未被识别为持久实体

 java.lang.IllegalArgumentException: Unsupported entity my.model.Person! Could not determine IsNewStrategy.
at org.springframework.data.support.IsNewStrategyFactorySupport.getIsNewStrategy(IsNewStrategyFactorySupport.java:48) ~[spring-data-commons-1.13.8.RELEASE.jar:na]
at org.springframework.data.auditing.IsNewAwareAuditingHandler.markAudited(IsNewAwareAuditingHandler.java:80) ~[spring-data-commons-1.13.8.RELEASE.jar:na]
at org.socialsignin.spring.data.dynamodb.mapping.event.AuditingEventListener.onBeforeSave(AuditingEventListener.java:44) ~[spring-data-dynamodb-4.5.5.jar:4.5.5]
at org.socialsignin.spring.data.dynamodb.mapping.event.AbstractDynamoDBEventListener.onApplicationEvent(AbstractDynamoDBEventListener.java:109) ~[spring-data-dynamodb-4.5.5.jar:4.5.5]

当我在调试器中单步执行框架代码时,我看到当检查目标类是否为持久实体类返回时抛出异常,作为回报false,它产生一个 null IsNewStrategy

堆栈跟踪表明这发生在审计侦听器执行期间。

我的实体类似乎没有被 Spring Data DynamoDB 识别为持久实体 - 如果通过@EnableDynamoDBAuditing. 如果我从配置中删除该注释,一切似乎都正常。我需要能够自动设置创建/更新日期字段——就像我使用 Spring Data JPA 一样。(在我的特殊情况下,到目前为止,我并不关心设置“createdBy”,所以我不需要auditorAwareRef在注释上设置属性。)仅在日期字段上@EnableDynamoDBAuditing使用注释就足够了吗?@DynamoDBAutoGeneratedTimestamp那么这样做的目的是@EnableDynamoDBAuditing什么?当后者存在时,为什么事情会破裂?

标签: javaspringspring-bootspring-dataamazon-dynamodb

解决方案


推荐阅读