Поля аудита данных Spring, помеченные как Updatable = false, не возвращаются в возвращаемую сущность при обновлении - PullRequest
0 голосов
/ 08 сентября 2018

Я использую аннотации Spring Data для добавления данных аудита в мои объекты, когда они сохраняются или обновляются. Когда я создаю сущность, createdBy, createdDate, lastModifiedBy и lastModifiedDate устанавливаются для объекта, возвращаемого repository.save().

ResourceEntity(id=ebbe1f3d-3359-4295-8c83-63eab21c4753, createdDate=2018-09-07T21:11:25.797, lastModifiedDate=2018-09-07T21:11:25.797, createdBy=5855070b-866f-4bc4-a18f-26b54f896a4b, lastModifiedBy=5855070b-866f-4bc4-a18f-26b54f896a4b)

К сожалению, когда я вызываю repository.save() для обновления существующей сущности, возвращенный объект не имеет установленных createdBy и createdDate.

 ResourceEntity(id=ebbe1f3d-3359-4295-8c83-63eab21c4753, createdDate=null, lastModifiedDate=2018-09-07T21:12:01.953, createdBy=null, lastModifiedBy=5855070b-866f-4bc4-a18f-26b54f896a4b)

Все поля в базе данных установлены правильно, и вызов repository.findOne() вне моего класса обслуживания возвращает объект со всеми полями, установленными правильно.

ResourceEntity(id=ebbe1f3d-3359-4295-8c83-63eab21c4753, createdDate=2018-09-07T21:11:25.797, lastModifiedDate=2018-09-07T21:12:01.953, createdBy=5855070b-866f-4bc4-a18f-26b54f896a4b, lastModifiedBy=5855070b-866f-4bc4-a18f-26b54f896a4b)

Но если я вызову repository.findOne() в службе сразу после вызова repository.save(), чтобы обновить сущность, я также получу объект обратно с createdBy и createdDate, установленными в ноль.

Вот моя сущность:

@Entity(name = "resource")
@EntityListeners(AuditingEntityListener.class)
@Table(name = "resource")
@Data
@EqualsAndHashCode(of = "id")
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ResourceEntity {

@Id
@org.hibernate.annotations.Type(type = "org.hibernate.type.PostgresUUIDType")
private UUID id;

@CreatedDate
@Column(nullable = false, updatable = false)
private LocalDateTime createdDate;

@LastModifiedDate
private LocalDateTime lastModifiedDate;

@CreatedBy
@Column(nullable = false, updatable = false)
@org.hibernate.annotations.Type(type = "org.hibernate.type.PostgresUUIDType")
private UUID createdBy;

@LastModifiedBy
@org.hibernate.annotations.Type(type = "org.hibernate.type.PostgresUUIDType")
private UUID lastModifiedBy;
}

Вот мой сервис:

@Component
public class ResourceService {
@Autowired
private ResourceRepository resourceRepository;

public ResourceEntity createResource(ResourceEntity resourceEntity) {
    return saveResource(resourceEntity);
}

public ResourceEntity updateResource(ResourceEntity resourceEntity) {
    return saveResource(resourceEntity);
}

public ResourceEntity getResource(UUID resourceId) {
    return resourceRepository.findOne(resourceId);
}

private ResourceEntity saveResource(ResourceEntity resourceEntity) {
    ResourceEntity savedResourceEntity = resourceRepository.save(resourceEntity);
    return savedResourceEntity;
}
}

Вот мой тест:

def "Test update"() {
    given:
    UUID id = aRandom.uuid()
    Resource resource = aRandom.resource().id(id).build()
    Resource savedResource = resourceClient.createResource(resource)

    when:
    Resource updatedResource = aRandom.resource().id(id).build()
    updatedResource = resourceClient.updateResource(updatedResource)

    then:
    Resource result = resourceClient.getResource(id)
    assert result.id == updatedResource.id
    assert result.createdBy == updatedResource.createdBy
    assert result.creationDate == updatedResource.creationDate
    assert result.lastModifiedBy == updatedResource.lastModifiedBy
    assert result.lastModifiedDate == updatedResource.lastModifiedDate
}

1 Ответ

0 голосов
/ 08 сентября 2018

Я пытался раньше, как это, когда мне нужно добавить информацию аудита.

У меня есть DataConfig класс, подобный этому.

@Configuration
@EnableJpaAuditing
public class DataConfig {

    @Bean
    public AuditorAware<UUID> auditorProvider() {
        return new YourSecurityAuditAware();
    }

    @Bean
    public DateTimeProvider dateTimeProvider() {
        return () -> Optional.of(Instant.from(ZonedDateTime.now()));
    }
}

Теперь вам нужен AuditorAware класс, чтобы получить информацию аудита. Так что этот класс будет таким;

public class XPorterSecurityAuditAware implements AuditorAware<UUID> {

    @Override
    public Optional<UUID> getCurrentAuditor() {
        //you can change UUID format as well
        return Optional.of(UUID.randomUUID());
    }
}

Надеюсь, это поможет вам.

...