审核 (@CreatedDate) 不适用于 Spring Boot Cassandra

问题描述 投票:0回答:2

我有一个简单的实体,我想让“createdDate”自动分配。

@CreatedDate
private LocalDateTime createdDate;

正如文档中所述,我还在我的 CassandraConfig 中添加了注释“@EnableCassandraAuditing”:

@Configuration
@EnableCassandraRepositories
@EnableCassandraAuditing
public class CassandraConfig extends AbstractCassandraConfiguration { 

但是它仍然不起作用..实体是使用createdDate = null创建的。 任何帮助表示赞赏。

spring spring-boot cassandra spring-data
2个回答
0
投票

根据文档说:

我们提供

@CreatedBy
@LastModifiedBy
来捕获创建的用户 或修改实体以及
@CreatedDate
@LastModifiedDate
捕捉这件事发生的时间点。

我认为最后一句话的意思是

capture the point in time this happened by some user.
因为我很久以前也有过同样的
issue

然后,如果您想

@CreatedDate
注释起作用,那么您需要提供当前的审核员。应该通过以下方式或仅使用第二个示例来创建您的自定义
Auditor Aware

第一个例子:

class SpringSecurityAuditorAware implements AuditorAware<User> {

    public Optional<User> getCurrentAuditor() {

        return Optional.ofNullable(SecurityContextHolder.getContext())
                 .map(SecurityContext::getAuthentication)
                 .filter(Authentication::isAuthenticated)
                 .map(Authentication::getPrincipal)
                 .map(User.class::cast);
    }
}

第二个例子:

class SpringSecurityAuditorAware implements AuditorAware<String> {

    public Optional<String> getCurrentAuditor() {
         return Optional.of("CurrentUser");
    }
}

注意

我找到了一个类似的答案,您可以检查@CreatedDate 不起作用答案


0
投票

正如另一个答案中所指出的,您需要一个

AuditorAware
实现来进行审计。您可以提供一个虚拟值。

但是,还有另一个问题可能会阻止

CreatedBy
CreatedDate
工作,即 Spring 可能无法检测到您的实体是新的,并且不会触发创建日期审核。这是因为Spring通过它的ID属性是否为空来检测所保存的实体是否是新的。然而,Spring 的 Cassandra 集成在很多情况下不支持自动生成 ID,这意味着您通常必须先填充实体的 ID,然后再将其传递到存储库的
save
方法。在这些情况下,实体不被视为“新”,也不会被审核为“创建”。

您可以通过将

modifyOnCreate
中的
false
设置为
EnableCassandraAuditing
并将
@CreatedDate
更改为
@LastModifiedDate
来检查是否是这个问题。如果您发现在插入新实体时现在正在填充该字段,则审核正在工作,但只是无法识别新插入。

要解决这个问题,你必须找到一种不同的方式来表明正在保存的实体是新的。这些方法记录在此处:https://docs.spring.io/spring-data/jdbc/docs/current/reference/html/#is-new-state-detection

我已成功执行以下操作:

@Entity
@Data
@NoArgsConstructor
@Table("my_entity")
public class MyEntity implements Persistable {
  @Column
  private UUID id;

  @Column
  private int someData;

  @Transient
  private boolean isNew = false;

  @Transient
  @Override
  public boolean isNew() {
    return this.isNew;
  }
}

然后,在您的服务类中,插入新实体时只需将

isNew
设置为
false

@Service
@RequiredArgsConstructor
public class MyEntityService {
  MyEntityRepository repository;

  public void createEntity(int someData) {
    UUID id = UUID.randomUUID();
    MyEntity newEntity = new MyEntity();
    newEntity.setId(id);
    newEntity.setSomeData(someData);
    newEntity.setIsNew(true);
    repository.save(newEntity);
  }

  public void updateEntity(UUID id, int someData) {
    MyEntity previousEntity = repository.findById(id);
    previousEntity.setSomeData(someData);
    // previousEntity.getIsNew() should return false
    repository.save(previousEntity);
  }
}

另请参阅此处发布的问题:https://github.com/spring-projects/spring-data-cassandra/issues/1124

© www.soinside.com 2019 - 2024. All rights reserved.