Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Пишем погодного телеграм-бота! ☀️
Встреча от 30.03.2025
Запись встречи -
YOUTUBE
RUTUBE
На сегодняшней встрече мы написали своего бота.🤖
При написании мы узнали и повторили:
🔜 Как вообще пишут бота и с какими библиотеками.
🔜 Как работает логика бота.
🔜 Как по REST передают json и как его парсить.
🔜 Настроили свой кэш и шедулер.
🔜 Как всегда допустил немного ошибок и успешно их решил)
Кстати в гите более полная версия того бота который я запускал Вам для теста!
Ссылка на Git - https://github.com/Oleborn/WeatherChatBot
Смотрите, комментируйте, задавайте вопросы! Обязательно подписывайтесь на ютуб и рутюб каналы!!!
Всем спасибо за участие и то что пришли, для меня это важно!
Надеюсь вы напишете своих ботов и обязательно похвастаете перед нами😉
Встреча от 30.03.2025
Запись встречи -
YOUTUBE
RUTUBE
На сегодняшней встрече мы написали своего бота.
При написании мы узнали и повторили:
Кстати в гите более полная версия того бота который я запускал Вам для теста!
Ссылка на Git - https://github.com/Oleborn/WeatherChatBot
Смотрите, комментируйте, задавайте вопросы! Обязательно подписывайтесь на ютуб и рутюб каналы!!!
Всем спасибо за участие и то что пришли, для меня это важно!
Надеюсь вы напишете своих ботов и обязательно похвастаете перед нами
Please open Telegram to view this post
VIEW IN TELEGRAM
Аннотация @CreatedBy
Аннотация @CreatedBy используется в Spring Data для автоматического заполнения поля информацией о пользователе, создавшем сущность. Это часть механизма аудита Spring Data, позволяющего автоматически отслеживать, кто и когда создавал или изменял сущности. Аннотация находится в пакете org.springframework.data.annotation.
Параметры аннотации
Аннотация @CreatedBy не имеет параметров. Она применяется к полям сущности, которые должны автоматически заполняться информацией о создателе.
Пример использования:
Жизненный цикл аннотации
Инициализация:
Аннотация активируется при включении аудита через @EnableJpaAuditing
Требуется регистрация AuditingEntityListener для сущности
Выполнение:
Перед сохранением новой сущности (при вызове save())
Spring автоматически определяет текущего пользователя и устанавливает значение поля
Обновление:
Поле заполняется только при создании сущности
Не изменяется при последующих обновлениях
Механизмы Spring и настройки Spring Boot
AuditingEntityListener:
Класс, обрабатывающий события жизненного цикла сущности
Автоматически заполняет аннотированные поля
AuditorAware:
Интерфейс для получения информации о текущем пользователе
Требуется реализация для работы @CreatedBy
EnableJpaAuditing:
Аннотация для активации механизма аудита
Настройки Spring Boot
Активация аудита:
Конфигурация сущности:
Настройки безопасности (если используется Spring Security):
Варианты настройки
Типы полей:
Может использоваться с любым типом (String, Long, UUID)
Чаще всего используется String для хранения имени пользователя
Интеграция с Spring Security:
Автоматическое получение имени текущего пользователя
Пример реализации AuditorAware:
Кастомные реализации:
Возможность использовать ID пользователя вместо имени
Интеграция с кастомными системами аутентификации
Комбинирование с другими аннотациями аудита:
#Java #Training #Hard #Spring #SpringDataJPA #CreatedBy
Аннотация @CreatedBy используется в Spring Data для автоматического заполнения поля информацией о пользователе, создавшем сущность. Это часть механизма аудита Spring Data, позволяющего автоматически отслеживать, кто и когда создавал или изменял сущности. Аннотация находится в пакете org.springframework.data.annotation.
Параметры аннотации
Аннотация @CreatedBy не имеет параметров. Она применяется к полям сущности, которые должны автоматически заполняться информацией о создателе.
Пример использования:
@Entity
@EntityListeners(AuditingEntityListener.class)
public class Document {
@CreatedBy
private String createdBy;
// Другие поля
}
Жизненный цикл аннотации
Инициализация:
Аннотация активируется при включении аудита через @EnableJpaAuditing
Требуется регистрация AuditingEntityListener для сущности
Выполнение:
Перед сохранением новой сущности (при вызове save())
Spring автоматически определяет текущего пользователя и устанавливает значение поля
Обновление:
Поле заполняется только при создании сущности
Не изменяется при последующих обновлениях
Механизмы Spring и настройки Spring Boot
AuditingEntityListener:
Класс, обрабатывающий события жизненного цикла сущности
Автоматически заполняет аннотированные поля
AuditorAware:
Интерфейс для получения информации о текущем пользователе
Требуется реализация для работы @CreatedBy
EnableJpaAuditing:
Аннотация для активации механизма аудита
Настройки Spring Boot
Активация аудита:
@Configuration
@EnableJpaAuditing
public class AuditConfig {
@Bean
public AuditorAware<String> auditorProvider() {
return () -> Optional.ofNullable(SecurityContextHolder.getContext())
.map(SecurityContext::getAuthentication)
.map(Authentication::getName);
}
}
Конфигурация сущности:
@Entity
@EntityListeners(AuditingEntityListener.class)
public class Order {
@CreatedBy
private String createdBy;
@CreatedDate
private LocalDateTime createdDate;
// Другие поля
}
Настройки безопасности (если используется Spring Security):
spring.security.user.name=admin
spring.security.user.password=secret
Варианты настройки
Типы полей:
Может использоваться с любым типом (String, Long, UUID)
Чаще всего используется String для хранения имени пользователя
Интеграция с Spring Security:
Автоматическое получение имени текущего пользователя
Пример реализации AuditorAware:
public class SecurityAuditorAware implements AuditorAware<String> {
@Override
public Optional<String> getCurrentAuditor() {
return Optional.ofNullable(SecurityContextHolder.getContext())
.map(SecurityContext::getAuthentication)
.filter(Authentication::isAuthenticated)
.map(Authentication::getName);
}
}
Кастомные реализации:
Возможность использовать ID пользователя вместо имени
Интеграция с кастомными системами аутентификации
Комбинирование с другими аннотациями аудита:
@CreatedBy
private String createdBy;
@CreatedDate
private LocalDateTime createdDate;
@LastModifiedBy
private String lastModifiedBy;
@LastModifiedDate
private LocalDateTime lastModifiedDate;
#Java #Training #Hard #Spring #SpringDataJPA #CreatedBy
Что выведет код?
#Tasks
import java.util.LinkedList;
public class Task310325 {
public static void main(String[] args) {
LinkedList<Integer> list = new LinkedList<>();
list.add(1);
list.add(2);
list.addFirst(3);
list.removeLast();
System.out.println(list.get(1));
}
}
#Tasks
Please open Telegram to view this post
VIEW IN TELEGRAM
Вопросы с собеседования 👩💻
Что делает метод charAt() в классе String?
Что делает метод charAt() в классе String?
Anonymous Quiz
2%
Удаляет символ из строки
10%
Добавляет символ в строку
69%
Возвращает символ по индексу
20%
Преобразует строку в массив символов
Аннотация @CreatedDate
Аннотация @CreatedDate используется в Spring Data для автоматического заполнения поля датой и временем создания сущности. Это часть механизма аудита Spring Data, который позволяет автоматически отслеживать временные метки создания и модификации сущностей. Аннотация находится в пакете org.springframework.data.annotation.
Параметры аннотации
Аннотация @CreatedDate не имеет параметров. Она применяется к полям сущности, которые должны автоматически заполняться временем создания.
Пример использования:
Поддерживаемые типы данных
Поле с аннотацией @CreatedDate может быть одного из следующих типов:
java.time.LocalDateTime
java.time.LocalDate
java.time.ZonedDateTime
java.util.Date
java.util.Calendar
java.sql.Timestamp
Long (для timestamp в миллисекундах)
Жизненный цикл аннотации
Инициализация:
Активируется при включении аудита через @EnableJpaAuditing
Требуется регистрация AuditingEntityListener для сущности
Выполнение:
Автоматически устанавливает текущую дату и время при первом сохранении сущности
Значение устанавливается один раз при создании и не изменяется при последующих обновлениях
Обновление:
Для отслеживания времени изменения следует использовать @LastModifiedDate
Механизмы Spring и настройки Spring Boot
AuditingEntityListener:
Обрабатывает события жизненного цикла сущности
Автоматически заполняет аннотированные поля датой/временем
EnableJpaAuditing:
Аннотация для активации механизма аудита
Настройки Spring Boot
Активация аудита в конфигурационном классе:
Конфигурация сущности:
Настройка часового пояса (опционально):
Варианты настройки и использования
Комбинирование с другими аннотациями аудита:
Использование разных типов даты/времени:
Кастомные форматы даты (при использовании с DTO):
Использование в проекциях Spring Data:
Особенности работы
Одноразовое заполнение:
Значение устанавливается только при первом сохранении сущности
Не изменяется при последующих обновлениях
Точность времени:
Зависит от базы данных и JPA-провайдера
Для высокой точности рекомендуется использовать java.time типы
Синхронизация времени:
Время берется с сервера, где выполняется приложение
Для распределенных систем рекомендуется использовать единый источник времени
#Java #Training #Hard #Spring #SpringDataJPA #CreatedDate
Аннотация @CreatedDate используется в Spring Data для автоматического заполнения поля датой и временем создания сущности. Это часть механизма аудита Spring Data, который позволяет автоматически отслеживать временные метки создания и модификации сущностей. Аннотация находится в пакете org.springframework.data.annotation.
Параметры аннотации
Аннотация @CreatedDate не имеет параметров. Она применяется к полям сущности, которые должны автоматически заполняться временем создания.
Пример использования:
@Entity
@EntityListeners(AuditingEntityListener.class)
public class Document {
@CreatedDate
private LocalDateTime createdAt;
// Другие поля
}
Поддерживаемые типы данных
Поле с аннотацией @CreatedDate может быть одного из следующих типов:
java.time.LocalDateTime
java.time.LocalDate
java.time.ZonedDateTime
java.util.Date
java.util.Calendar
java.sql.Timestamp
Long (для timestamp в миллисекундах)
Жизненный цикл аннотации
Инициализация:
Активируется при включении аудита через @EnableJpaAuditing
Требуется регистрация AuditingEntityListener для сущности
Выполнение:
Автоматически устанавливает текущую дату и время при первом сохранении сущности
Значение устанавливается один раз при создании и не изменяется при последующих обновлениях
Обновление:
Для отслеживания времени изменения следует использовать @LastModifiedDate
Механизмы Spring и настройки Spring Boot
AuditingEntityListener:
Обрабатывает события жизненного цикла сущности
Автоматически заполняет аннотированные поля датой/временем
EnableJpaAuditing:
Аннотация для активации механизма аудита
Настройки Spring Boot
Активация аудита в конфигурационном классе:
@Configuration
@EnableJpaAuditing
public class AuditConfig {
// Дополнительные настройки при необходимости
}
Конфигурация сущности:
@Entity
@EntityListeners(AuditingEntityListener.class)
public class Order {
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
// Другие поля
}
Настройка часового пояса (опционально):
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
Варианты настройки и использования
Комбинирование с другими аннотациями аудита:
@CreatedDate
private LocalDateTime createdAt;
@CreatedBy
private String createdBy;
@LastModifiedDate
private LocalDateTime updatedAt;
@LastModifiedBy
private String updatedBy;
Использование разных типов даты/времени:
@CreatedDate
private Date createdAt; // java.util.Date
@CreatedDate
private Long createdTimestamp; // timestamp в миллисекундах
Кастомные форматы даты (при использовании с DTO):
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@CreatedDate
private LocalDateTime createdAt;
Использование в проекциях Spring Data:
public interface OrderProjection {
@Value("#{target.createdAt}")
String getFormattedCreatedAt();
}
Особенности работы
Одноразовое заполнение:
Значение устанавливается только при первом сохранении сущности
Не изменяется при последующих обновлениях
Точность времени:
Зависит от базы данных и JPA-провайдера
Для высокой точности рекомендуется использовать java.time типы
Синхронизация времени:
Время берется с сервера, где выполняется приложение
Для распределенных систем рекомендуется использовать единый источник времени
#Java #Training #Hard #Spring #SpringDataJPA #CreatedDate
Аннотации @LastModifiedBy и @LastModifiedDate
Эти аннотации являются частью механизма аудита Spring Data и используются для автоматического отслеживания:
@LastModifiedBy - кто последним изменял сущность
@LastModifiedDate - когда были внесены последние изменения
Обе аннотации находятся в пакете org.springframework.data.annotation.
Аннотация @LastModifiedBy
Параметры
Как и @CreatedBy, аннотация не имеет параметров. Применяется к полям, которые должны хранить информацию о последнем редакторе.
Поддерживаемые типы
String (для имен пользователей)
Long/UUID (для ID пользователей)
Любой другой тип, возвращаемый реализацией AuditorAware
Пример использования
Аннотация @LastModifiedDate
Параметры
Не имеет параметров. Применяется к полям даты/времени.
Поддерживаемые типы
Те же, что и для @CreatedDate:
java.time типы (LocalDateTime, ZonedDateTime)
java.util.Date
Long (timestamp)
Пример использования
Комбинированное использование
Полный пример аудита
Особенности поведения
Инициализация:
@CreatedBy/Date заполняются только при создании
@LastModifiedBy/Date обновляются при каждом изменении
Сценарий обновления:
Настройка в Spring Boot
Обязательная конфигурация
Активация аудита:
Реализация AuditorAware (для @CreatedBy и @LastModifiedBy):
Дополнительные настройки
Для JPA репозиториев:
Настройка формата даты (опционально):
Практические рекомендации
Для веб-приложений:
Комбинируйте с Spring Security для автоматического определения пользователя
Используйте DTO с аннотацией @JsonFormat для красивого отображения дат
Для микросервисов:
Вместо имени пользователя можно хранить ID сервиса
Используйте единый часовой пояс (UTC) для всех сервисов
Оптимизация запросов:
Интеграция с историей изменений:
Можно создать отдельную таблицу для хранения полной истории изменений
Использовать @PreUpdate и @PrePersist для дополнительного логирования
Ограничения и решения
Проблема: Не обновляется при косвенных изменениях
Решение: Явно вызывать save() или использовать @Version
Проблема: Неточное время в кластере
Решение: Использовать NTP или временные сервисы
Проблема: Кастомные редакторы (например, системные задания)
Решение: Переопределить AuditorAware для специфических случаев
#Java #Training #Hard #Spring #SpringDataJPA #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
Что выведет код?
#Tasks
public class Task010425 {
public static void main(String[] args) {
double x = -2.5;
double result = Math.abs(Math.floor(x));
System.out.println(result);
}
}
#Tasks
Please open Telegram to view this post
VIEW IN TELEGRAM
Вопросы с собеседования 👩💻
Какой метод используется для замены символов в строке?
Какой метод используется для замены символов в строке?
Anonymous Quiz
93%
replace()
7%
swap()
0%
change()
0%
substitute()
Аннотация @Version
Аннотация @Version используется в JPA для реализации оптимистичной блокировки (optimistic locking) - механизма контроля параллельного доступа к данным без использования явных блокировок на уровне базы данных. Находится в пакете javax.persistence.
Параметры аннотации
Аннотация не имеет параметров. Применяется к единственному полю сущности, которое должно быть:
Числовым типом (int, Integer, long, Long)
Типом java.sql.Timestamp
Пример использования
Жизненный цикл аннотации
Инициализация:
При создании сущности поле получает значение 0 (или текущее время для Timestamp)
Обновление:
При каждом обновлении сущности значение автоматически увеличивается на 1
JPA проверяет, что значение в БД совпадает с исходным значением перед обновлением
Конфликт:
Если значение в БД изменилось (другой транзакцией), выбрасывается OptimisticLockException
Механизм работы
При чтении сущности:
При обновлении:
Выполняется SQL вида:
Если версия изменилась:
Количество обновленных строк = 0 → OptimisticLockException
Обработка исключений:
Практическое использование
Базовый сценарий:
Проверка версии вручную:
Использование DTO:
Особенности реализации
Типы полей:
Для числовых типов: последовательное увеличение
Для Timestamp: текущее время сервера
Поведение при:
Создании: устанавливается 0
Клонировании: версия не копируется
Удалении: проверка версии не выполняется (настраивается через @OptimisticLocking)
Производительность:
Минимальные накладные расходы
Не требует блокировок в БД
Альтернативы и дополнения
Пессимистичная блокировка:
Дополнительные аннотации Hibernate:
@OptimisticLocking - для настройки поведения
@DynamicUpdate - обновлять только измененные поля
Кастомные стратегии:
Реализация собственного механизма через @PreUpdate
#Java #Training #Hard #Spring #SpringDataJPA #Version
Аннотация @Version используется в JPA для реализации оптимистичной блокировки (optimistic locking) - механизма контроля параллельного доступа к данным без использования явных блокировок на уровне базы данных. Находится в пакете javax.persistence.
Параметры аннотации
Аннотация не имеет параметров. Применяется к единственному полю сущности, которое должно быть:
Числовым типом (int, Integer, long, Long)
Типом java.sql.Timestamp
Пример использования
@Entity
public class Product {
@Id
private Long id;
@Version
private Integer version;
// другие поля
}
Жизненный цикл аннотации
Инициализация:
При создании сущности поле получает значение 0 (или текущее время для Timestamp)
Обновление:
При каждом обновлении сущности значение автоматически увеличивается на 1
JPA проверяет, что значение в БД совпадает с исходным значением перед обновлением
Конфликт:
Если значение в БД изменилось (другой транзакцией), выбрасывается OptimisticLockException
Механизм работы
При чтении сущности:
Product product = em.find(Product.class, 1L);
// product.version = 1 (текущее значение в БД)
При обновлении:
product.setPrice(newPrice);
em.merge(product);
Выполняется SQL вида:
UPDATE product
SET ..., version = version + 1
WHERE id = 1 AND version = 1
Если версия изменилась:
Количество обновленных строк = 0 → OptimisticLockException
Обработка исключений:
@ExceptionHandler(OptimisticLockException.class)
public ResponseEntity<String> handleConflict(OptimisticLockException ex) {
return ResponseEntity.status(HttpStatus.CONFLICT).body("Объект был изменен другим пользователем");
}
Практическое использование
Базовый сценарий:
@Service
@Transactional
public class ProductService {
public void updatePrice(Long id, BigDecimal newPrice) {
Product product = productRepository.findById(id).orElseThrow();
product.setPrice(newPrice);
// При коммите транзакции версия автоматически увеличится
}
}
Проверка версии вручную:
public void updateWithVersionCheck(Long id, Integer expectedVersion, Product update) {
Product product = productRepository.findById(id).orElseThrow();
if (!product.getVersion().equals(expectedVersion)) {
throw new OptimisticLockException("Версия не совпадает");
}
// ... обновление
}
Использование DTO:
public class ProductDto {
private Long id;
private Integer version;
// другие поля
public Product toEntity() {
Product product = new Product();
product.setId(this.id);
product.setVersion(this.version);
// ...
return product;
}
}
Особенности реализации
Типы полей:
Для числовых типов: последовательное увеличение
Для Timestamp: текущее время сервера
Поведение при:
Создании: устанавливается 0
Клонировании: версия не копируется
Удалении: проверка версии не выполняется (настраивается через @OptimisticLocking)
Производительность:
Минимальные накладные расходы
Не требует блокировок в БД
Альтернативы и дополнения
Пессимистичная блокировка:
@Lock(LockModeType.PESSIMISTIC_WRITE)
Product findByIdForUpdate(Long id);
Дополнительные аннотации Hibernate:
@OptimisticLocking - для настройки поведения
@DynamicUpdate - обновлять только измененные поля
Кастомные стратегии:
Реализация собственного механизма через @PreUpdate
#Java #Training #Hard #Spring #SpringDataJPA #Version