Java for Beginner
673 subscribers
556 photos
156 videos
12 files
848 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Аннотации @LastModifiedBy и @LastModifiedDate

Эти аннотации являются частью механизма аудита Spring Data и используются для автоматического отслеживания:
@LastModifiedBy - кто последним изменял сущность
@LastModifiedDate - когда были внесены последние изменения

Обе аннотации находятся в пакете org.springframework.data.annotation.

Аннотация @LastModifiedBy

Параметры
Как и @CreatedBy, аннотация не имеет параметров. Применяется к полям, которые должны хранить информацию о последнем редакторе.

Поддерживаемые типы
String (для имен пользователей)
Long/UUID (для ID пользователей)

Любой другой тип, возвращаемый реализацией AuditorAware

Пример использования
@Entity
@EntityListeners(AuditingEntityListener.class)
public class Document {
@LastModifiedBy
private String lastModifiedBy;

// Другие поля
}


Аннотация @LastModifiedDate

Параметры
Не имеет параметров. Применяется к полям даты/времени.

Поддерживаемые типы
Те же, что и для @CreatedDate:
java.time типы (LocalDateTime, ZonedDateTime)
java.util.Date
Long (timestamp)


Пример использования
@Entity
@EntityListeners(AuditingEntityListener.class)
public class Document {
@LastModifiedDate
private LocalDateTime lastModifiedAt;

// Другие поля
}


Комбинированное использование

Полный пример аудита
@Entity
@EntityListeners(AuditingEntityListener.class)
public class Product {
@Id
private Long id;

@CreatedBy
private String createdBy;

@CreatedDate
private LocalDateTime createdAt;

@LastModifiedBy
private String lastModifiedBy;

@LastModifiedDate
private LocalDateTime lastModifiedAt;

// Бизнес-поля
private String name;
private BigDecimal price;
}


Особенности поведения

Инициализация:
@CreatedBy/Date заполняются только при создании
@LastModifiedBy/Date обновляются при каждом изменении

Сценарий обновления:
product.setPrice(new BigDecimal("99.99"));
productRepository.save(product);
Поля lastModifiedBy/At будут автоматически обновлены
Поля createdBy/At останутся без изменений


Настройка в Spring Boot

Обязательная конфигурация
Активация аудита:
@SpringBootApplication
@EnableJpaAuditing
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}


Реализация AuditorAware (для @CreatedBy и @LastModifiedBy):
@Bean
public AuditorAware<String> auditorAware() {
return () -> Optional.ofNullable(SecurityContextHolder.getContext())
.map(SecurityContext::getAuthentication)
.filter(Authentication::isAuthenticated)
.map(Authentication::getName);
}


Дополнительные настройки
Для JPA репозиториев:
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true


Настройка формата даты (опционально):
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=UTC


Практические рекомендации


Для веб-приложений:
Комбинируйте с Spring Security для автоматического определения пользователя
Используйте DTO с аннотацией
@JsonFormat для красивого отображения дат

Для микросервисов:
Вместо имени пользователя можно хранить ID сервиса
Используйте единый часовой пояс (UTC) для всех сервисов


Оптимизация запросов:
@Query("SELECT p FROM Product p WHERE p.lastModifiedAt > :since")
List<Product> findRecentlyModified(@Param("since") LocalDateTime since);


Интеграция с историей изменений:
Можно создать отдельную таблицу для хранения полной истории изменений
Использовать
@PreUpdate и @PrePersist для дополнительного логирования

Ограничения и решения

Проблема: Не обновляется при косвенных изменениях
Решение: Явно вызывать save() или использовать
@Version

Проблема: Неточное время в кластере
Решение: Использовать NTP или временные сервисы


Проблема: Кастомные редакторы (например, системные задания)
Решение: Переопределить AuditorAware для специфических случаев


#Java #Training #Hard #Spring #SpringDataJPA #LastModifiedBy #LastModifiedDate