Spring-data-DynamoDB в приложении Spring Boot: классы @DynamoDBTable не распознаются как постоянные сущности, если настроено @EnableDynamoDBAuditing - PullRequest
0 голосов
/ 08 июня 2018

Я пытаюсь добавить поддержку DynamoDB в существующее приложение Spring Boot / Spring Data JPA - с помощью spring-data-DynamodB .

  • Spring Boot версия 1.5.12.RELEASE
  • spring-data-DynamodBB версия 4.5.5

Я хочу иметь возможность переключаться между JPA (Oracle, HSQL) и DynamoDB, используя взаимоисключающие профили Spring (jpa и 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.

Обратите внимание, что я специально пытаюсь исключитьлюбая автоконфигурация JPA, когда активирован профиль dynamodb.Для DynamoDB я хочу включить аудит через EnableDynamoDBAuditing - я предполагаю, что это spring-data-dynamodb эквивалент Spring 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.
}

И соответствующий репозиторий остается неизменным (я только добавил *Аннотация 1046 *, следуя примеру):

 @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, что, в свою очередь, приводит к нулю IsNewStrategy.

Трассировка стека указывает, что это происходит во время выполнения прослушивателя аудита.

Мои классы сущностей, по-видимому, не распознаются как сохраняемые сущности Spring Data DynamoDB - если аудит DynamoDB включен через @EnableDynamoDBAuditing.Если я удаляю эту аннотацию из моей конфигурации, кажется, все работает нормально.Мне нужно иметь возможность автоматически устанавливать поля даты создания / обновления - так же, как я это делаю с Spring Data JPA.(В моем конкретном случае до сих пор меня не волнует настройка «createBy», поэтому мне не нужно устанавливать свойство auditorAwareRef для аннотации @EnableDynamoDBAuditing.) Достаточно ли просто использовать @DynamoDBAutoGeneratedTimestampаннотация на полях даты?Какова цель @EnableDynamoDBAuditing тогда?И почему вещи ломаются, когда последний присутствует?

...