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

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

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Аннотации JPA: @Embeddable, @Embedded, @ElementCollection, @Inheritance, @Cacheable, @Lock, @EntityListeners, @SQLInsert, @SQLUpdate, @SQLDelete

1. @Embeddable и @Embedded

Аннотация
@Embeddable обозначает класс, который будет встраиваться в другие сущности, а @Embedded — указывает, что поле встраивает такой класс.
@Embeddable
public class Address {
private String street;
private String city;
}

@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Embedded
private Address address;
}


2. @ElementCollection

Используется для хранения коллекций простых типов или встраиваемых объектов.

@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ElementCollection
private List<String> tags;
}


3.
@Inheritance

Настраивает стратегию наследования для сущностей.
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Vehicle {
@Id
private Long id;
}

@Entity
public class Car extends Vehicle {
private int seatingCapacity;
}


4. @Cacheable

Обозначает, что сущность может быть закеширована.
@Entity
@Cacheable
public class Product {
@Id
private Long id;
private String name;
}


5. @Lock

Используется для управления блокировками данных.

@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("SELECT u FROM User u WHERE u.id = :id")
User findForUpdate(@Param("id") Long id);


6.
@EntityListeners

Позволяет подключать слушатели для отслеживания событий сущности.

@Entity
@EntityListeners(AuditListener.class)
public class Order {
@Id
private Long id;
}


7.
@SQLInsert, @SQLUpdate, @SQLDelete

Эти аннотации позволяют задать кастомные SQL-запросы для операций вставки, обновления и удаления.

@SQLInsert(sql = "INSERT INTO user_audit (id, username) VALUES (?, ?)")
@SQLDelete(sql = "DELETE FROM user_audit WHERE id = ?")
@Entity
public class UserAudit {
@Id
private Long id;
}


#Java #Training #Spring #Embeddable, #Embedded, #ElementCollection, #Inheritance, #Cacheable, #Lock, #EntityListeners, #SQLInsert, #SQLUpdate, #SQLDelete
Аннотации @Cacheable и @CacheEvict

@Cacheable

Аннотация @Cacheable указывает, что результат метода должен быть сохранён в кеше. Если метод вызывается с теми же аргументами, то возвращается кешированное значение, а не выполняется метод.

Параметры

value / cacheNames (обязательный параметр)
Имя кеша, в который сохраняется результат. Можно указать одно или несколько значений.
```
@Cacheable("usersCache")
```
key (опциональный)
Позволяет задать ключ для кеша. Если не указано, ключ формируется автоматически на основе аргументов метода.
Можно использовать SpEL (Spring Expression Language) для создания ключей.
```
@Cacheable(value = "usersCache", key = "#id")
public User getUser(Long id) {
return userRepository.findById(id).orElse(null);
}
```

condition (опциональный)
Условие, при котором результат метода будет закеширован. Используется SpEL. Если условие не выполнено, кеширование не происходит.
@Cacheable(value = "usersCache", condition = "#id > 10")
public User getUser(Long id) {
return userRepository.findById(id).orElse(null);
}


unless (опциональный)
Условие, при котором результат НЕ будет кешироваться, даже если метод выполнен. Отличается от condition, так как проверяется после выполнения метода.
@Cacheable(value = "usersCache", unless = "#result == null")
public User getUser(Long id) {
return userRepository.findById(id).orElse(null);
}


sync (опциональный)
Если true, запросы для одного и того же ключа будут синхронизированы, чтобы предотвратить одновременное выполнение метода для одного ключа.
@Cacheable(value = "usersCache", sync = true)
public User getUser(Long id) {
return userRepository.findById(id).orElse(null);
}


Пример использования

1. Простое кеширование
Кеширование результата метода:
@Cacheable("usersCache")
public User getUser(Long id) {
System.out.println("Fetching user from database...");
return userRepository.findById(id).orElse(null);
}
Первый вызов с ID 1 сохранит результат в кеше.
Повторные вызовы с тем же ID вернут кешированные данные.


2. Сложный ключ для кеша
@Cacheable(value = "usersCache", key = "#user.id + '-' + #user.name")
public User getUserWithCustomKey(User user) {
return userRepository.findById(user.getId()).orElse(null);
}
Здесь ключом будет строка, содержащая ID и имя пользователя.


3. Использование условий
@Cacheable(value = "usersCache", condition = "#id > 1000")
public User getUser(Long id) {
return userRepository.findById(id).orElse(null);
}
Данные кешируются только для ID больше 1000.


#Java #Training #Spring #Cacheable
@CacheEvict

Аннотация @CacheEvict используется для удаления записей из кеша. Это необходимо, когда данные в кеше устарели, например, после обновления или удаления записи.

Параметры

value / cacheNames (обязательный параметр)
Указывает имя кеша, из которого нужно удалить записи.
@CacheEvict("usersCache")


key (опциональный)
Указывает ключ, который нужно удалить. Если не указано, удаляется запись, соответствующая ключу, сформированному из аргументов метода.
@CacheEvict(value = "usersCache", key = "#id")
public void deleteUser(Long id) {
userRepository.deleteById(id);
}


allEntries (опциональный)
Если true, очищает весь кеш. Используется для полного удаления всех записей в кеше.
@CacheEvict(value = "usersCache", allEntries = true)
public void clearCache() {
System.out.println("Cache cleared!");
}


beforeInvocation (опциональный)
Если true, удаление из кеша происходит до выполнения метода. По умолчанию удаление происходит после успешного выполнения метода.
@CacheEvict(value = "usersCache", key = "#id", beforeInvocation = true)
public void deleteUser(Long id) {
throw new RuntimeException("Error occurred!");
}


Примеры использования

1. Удаление записи из кеша по ключу
@CacheEvict(value = "usersCache", key = "#id")
public void updateUser(Long id, User user) {
userRepository.save(user);
}
Обновляем пользователя и удаляем устаревшие данные из кеша.


2. Очистка всего кеша

@CacheEvict(value = "usersCache", allEntries = true)
public void clearAllUsersCache() {
System.out.println("All users cache cleared!");
}
Этот метод полностью очищает кеш usersCache.


3. Очистка перед выполнением метода

@CacheEvict(value = "usersCache", key = "#id", beforeInvocation = true)
public void deleteUser(Long id) {
// Логика удаления пользователя
userRepository.deleteById(id);
}
Кеш удаляется перед удалением пользователя из базы.


Совместное использование @Cacheable и @CacheEvict

Эти аннотации можно использовать вместе для полного управления кешем.

@Service
public class ProductService {

@Cacheable("productCache")
public Product getProduct(Long id) {
System.out.println("Fetching product from database...");
return productRepository.findById(id).orElse(null);
}

@CacheEvict(value = "productCache", key = "#id")
public void updateProduct(Long id, Product product) {
System.out.println("Updating product in database...");
productRepository.save(product);
}

@CacheEvict(value = "productCache", allEntries = true)
public void clearAllProductsCache() {
System.out.println("Clearing all product cache...");
}
}


Метод getProduct кеширует продукт.
Метод updateProduct удаляет устаревшие данные из кеша для обновлённого продукта.
Метод clearAllProductsCache очищает весь кеш продуктов.


Советы по использованию

Выбирайте правильный ключ: Убедитесь, что ключ уникален и логичен.
Учитывайте размер кеша: Не храните в кеше слишком большие данные.
Обновляйте кеш своевременно: Используйте
@CacheEvict для предотвращения устаревания данных.
Избегайте чрезмерного кеширования: Не кешируйте часто изменяющиеся данные.


#Java #Training #Spring #Cacheable #CacheEvict
Аннотации @Cache и @Cacheable в Hibernate

Аннотации
@Cache и @Cacheable относятся к кешированию сущностей и коллекций в Hibernate. Они позволяют оптимизировать производительность за счёт хранения часто используемых данных в памяти, уменьшая количество обращений к базе данных.

@Cache (org.hibernate.annotations.Cache) – настраивает стратегию кеширования для сущности или коллекции.
@Cacheable (javax.persistence.Cacheable / jakarta.persistence.Cacheable) – указывает, что сущность может быть кеширована (используется вместе с @Cache).

@Cache (Hibernate)

Параметры:
usage (CacheConcurrencyStrategy) – стратегия кеширования:

READ_ONLY – только для чтения (если сущность не изменяется).
NONSTRICT_READ_WRITE – кеш обновляется асинхронно при изменениях.
READ_WRITE – гарантирует согласованность через мягкие блокировки.
TRANSACTIONAL – полная поддержка транзакций (для JTA).


region (опционально)имя региона кеша (если используется несколько кешей, например, Ehcache, Hazelcast).

include (CacheInclude) указывает, включать ли ленивые поля в кеш (ALL или NON_LAZY).

Пример:
@Entity
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "employees")
public class Employee { ... }


@Cacheable (JPA)

Указывает, что сущность поддерживает кеширование.
Работает в паре с
@Cache (Hibernate) или настройками JPA-провайдера.
Если
@Cacheable(false), сущность игнорируется кешем, даже если кеширование включено глобально.

Пример:
@Entity
@Cacheable(true) // Включено кеширование (по умолчанию true)
public class Product { ... }


Механизмы кеширования в Hibernate

Уровни кеширования

Кеш первого уровня (Session)
Автоматический, живет в рамках одной сессии (EntityManager).
Не требует
@Cache.

Кеш второго уровня (SessionFactory)
Общий для всех сессий.
Требует явного объявления (
@Cache + @Cacheable).

Кеш запросов (Query Cache)
Кеширует результаты JPQL/HQL-запросов.

Включается отдельно:
spring.jpa.properties.hibernate.cache.use_query_cache=true


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

Включение кеша второго уровня
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
(Пример для Ehcache; также поддерживаются Infinispan, Hazelcast, Redis.)


Указание кешируемых сущностей

Через @Cache + @Cacheable.

Или глобально в application.properties:
spring.jpa.properties.javax.persistence.sharedCache.mode=ALL
(Варианты: ALL, NONE, ENABLE_SELECTIVE, DISABLE_SELECTIVE.)


Настройка поставщика кеша

Например, для Ehcache:
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>


И файл ehcache.xml в resources/.


Когда использовать?

@Cache + @Cacheable – для часто читаемых, редко изменяемых данных (справочники, настройки).
READ_ONLY – если сущности никогда не обновляются (например, Country, City).
READ_WRITE – если данные изменяются, но требуется высокая скорость чтения.
Избегать для часто изменяемых данных (кеш будет постоянно инвалидироваться).


#Java #Training #Hard #Spring #Hibernate #Cache #Cacheable