Аннотация @Modifying
Аннотация @Modifying используется в Spring Data JPA для указания того, что метод репозитория выполняет модифицирующие операции (например, UPDATE, DELETE, INSERT) в базе данных. Она применяется в сочетании с аннотацией @Query и находится в пакете org.springframework.data.jpa.repository.
Параметры аннотации
flushAutomatically (необязательный):
Тип: boolean.
Значение по умолчанию: false.
Описание: Если установлено в true, то перед выполнением запроса будет выполнен сброс (flush) контекста (Persistence Context). Это гарантирует, что все ожидающие изменения будут синхронизированы с базой данных перед выполнением модифицирующего запроса.
Пример:
clearAutomatically (необязательный):
Тип: boolean.
Значение по умолчанию: false.
Описание: Если установлено в true, то после выполнения запроса будет очищен (clear) контекст (Persistence Context). Это полезно, чтобы избежать использования устаревших данных из кэша первого уровня.
Пример:
Жизненный цикл аннотации
Инициализация:
Аннотация @Modifying обрабатывается во время инициализации Spring-контекста. Spring Data JPA анализирует методы репозитория, помеченные @Modifying, и настраивает их для выполнения модифицирующих операций.
Выполнение:
Когда метод репозитория вызывается, Spring Data JPA выполняет запрос, указанный в @Query, с учетом настроек @Modifying. Если flushAutomatically = true, выполняется сброс контекста перед запросом. Если clearAutomatically = true, контекст очищается после запроса.
Уничтожение:
Аннотация не имеет явного жизненного цикла уничтожения, так как она используется только для конфигурации выполнения запросов.
Механизмы Spring, связанные с @Modifying
Spring Data JPA:
Spring Data JPA предоставляет реализацию репозиториев, которая автоматически обрабатывает аннотацию @Modifying. Она интегрируется с JPA-провайдером (например, Hibernate) для выполнения модифицирующих запросов.
JPA-провайдер:
JPA-провайдер (например, Hibernate) отвечает за выполнение модифицирующих запросов. Для операций UPDATE и DELETE JPA-провайдер использует механизм EntityManager.
Транзакционность:
Методы, помеченные @Modifying, должны выполняться в транзакции. Если транзакция не настроена, Spring Data JPA выбросит исключение. Транзакционность можно настроить с помощью аннотации @Transactional.
Spring Boot автоматически настраивает менеджер транзакций (PlatformTransactionManager). Для методов с @Modifying рекомендуется явно указать транзакционность:
Варианты настройки
Использование flushAutomatically:
Установка flushAutomatically = true полезна, если в контексте есть изменения, которые должны быть синхронизированы с базой данных перед выполнением модифицирующего запроса.
Использование clearAutomatically:
Установка clearAutomatically = true полезна, если после выполнения модифицирующего запроса необходимо избежать использования устаревших данных из кэша первого уровня.
Комбинирование с @Query:
Аннотация @Modifying всегда используется вместе с @Query. Например:
Использование @Transactional:
Методы с @Modifying должны быть помечены аннотацией @Transactional, чтобы гарантировать атомарность операций.
#Java #Training #Hard #Spring #SpringDataJPA #Modifying
Аннотация @Modifying используется в Spring Data JPA для указания того, что метод репозитория выполняет модифицирующие операции (например, UPDATE, DELETE, INSERT) в базе данных. Она применяется в сочетании с аннотацией @Query и находится в пакете org.springframework.data.jpa.repository.
Параметры аннотации
flushAutomatically (необязательный):
Тип: boolean.
Значение по умолчанию: false.
Описание: Если установлено в true, то перед выполнением запроса будет выполнен сброс (flush) контекста (Persistence Context). Это гарантирует, что все ожидающие изменения будут синхронизированы с базой данных перед выполнением модифицирующего запроса.
Пример:
@Modifying(flushAutomatically = true)
@Query("UPDATE User u SET u.active = false WHERE u.lastLogin < :date")
void deactivateUsers(@Param("date") LocalDate date);
clearAutomatically (необязательный):
Тип: boolean.
Значение по умолчанию: false.
Описание: Если установлено в true, то после выполнения запроса будет очищен (clear) контекст (Persistence Context). Это полезно, чтобы избежать использования устаревших данных из кэша первого уровня.
Пример:
@Modifying(clearAutomatically = true)
@Query("DELETE FROM User u WHERE u.active = false")
void deleteInactiveUsers();
Жизненный цикл аннотации
Инициализация:
Аннотация @Modifying обрабатывается во время инициализации Spring-контекста. Spring Data JPA анализирует методы репозитория, помеченные @Modifying, и настраивает их для выполнения модифицирующих операций.
Выполнение:
Когда метод репозитория вызывается, Spring Data JPA выполняет запрос, указанный в @Query, с учетом настроек @Modifying. Если flushAutomatically = true, выполняется сброс контекста перед запросом. Если clearAutomatically = true, контекст очищается после запроса.
Уничтожение:
Аннотация не имеет явного жизненного цикла уничтожения, так как она используется только для конфигурации выполнения запросов.
Механизмы Spring, связанные с @Modifying
Spring Data JPA:
Spring Data JPA предоставляет реализацию репозиториев, которая автоматически обрабатывает аннотацию @Modifying. Она интегрируется с JPA-провайдером (например, Hibernate) для выполнения модифицирующих запросов.
JPA-провайдер:
JPA-провайдер (например, Hibernate) отвечает за выполнение модифицирующих запросов. Для операций UPDATE и DELETE JPA-провайдер использует механизм EntityManager.
Транзакционность:
Методы, помеченные @Modifying, должны выполняться в транзакции. Если транзакция не настроена, Spring Data JPA выбросит исключение. Транзакционность можно настроить с помощью аннотации @Transactional.
Spring Boot автоматически настраивает менеджер транзакций (PlatformTransactionManager). Для методов с @Modifying рекомендуется явно указать транзакционность:
@Transactional
@Modifying
@Query("UPDATE User u SET u.active = false WHERE u.lastLogin < :date")
void deactivateUsers(@Param("date") LocalDate date);
Варианты настройки
Использование flushAutomatically:
Установка flushAutomatically = true полезна, если в контексте есть изменения, которые должны быть синхронизированы с базой данных перед выполнением модифицирующего запроса.
Использование clearAutomatically:
Установка clearAutomatically = true полезна, если после выполнения модифицирующего запроса необходимо избежать использования устаревших данных из кэша первого уровня.
Комбинирование с @Query:
Аннотация @Modifying всегда используется вместе с @Query. Например:
Использование @Transactional:
Методы с @Modifying должны быть помечены аннотацией @Transactional, чтобы гарантировать атомарность операций.
#Java #Training #Hard #Spring #SpringDataJPA #Modifying
Аннотация @Param
Аннотация @Param используется в Spring Data JPA для привязки параметров метода к именованным параметрам в JPQL или нативных SQL-запросах. Она позволяет явно указать, какие аргументы метода должны быть переданы в запрос. Аннотация находится в пакете org.springframework.data.repository.query.
Параметры аннотации
value (обязательный):
Тип: String.
Описание: Указывает имя параметра, которое будет использоваться в запросе. Это имя должно совпадать с именем параметра в запросе, указанном в @Query.
Пример:
Жизненный цикл аннотации
Инициализация:
Аннотация @Param обрабатывается во время инициализации Spring-контекста. Spring Data JPA анализирует методы репозитория и связывает параметры метода с именованными параметрами в запросе.
Выполнение:
Когда метод репозитория вызывается, Spring Data JPA подставляет значения параметров метода в запрос, используя имена, указанные в @Param.
Уничтожение:
Аннотация не имеет явного жизненного цикла уничтожения, так как она используется только для привязки параметров.
Варианты настройки
Использование в JPQL:
Аннотация @Param используется для привязки параметров в JPQL-запросах:
Использование в нативных SQL-запросах:
Аннотация @Param также может использоваться в нативных SQL-запросах:
Использование с @Modifying:
Аннотация @Param может использоваться в методах, помеченных @Modifying, для выполнения модифицирующих операций:
#Java #Training #Hard #Spring #SpringDataJPA #Param
Аннотация @Param используется в Spring Data JPA для привязки параметров метода к именованным параметрам в JPQL или нативных SQL-запросах. Она позволяет явно указать, какие аргументы метода должны быть переданы в запрос. Аннотация находится в пакете org.springframework.data.repository.query.
Параметры аннотации
value (обязательный):
Тип: String.
Описание: Указывает имя параметра, которое будет использоваться в запросе. Это имя должно совпадать с именем параметра в запросе, указанном в @Query.
Пример:
@Query("SELECT u FROM User u WHERE u.email = :email")
User findByEmail(@Param("email") String email);
Жизненный цикл аннотации
Инициализация:
Аннотация @Param обрабатывается во время инициализации Spring-контекста. Spring Data JPA анализирует методы репозитория и связывает параметры метода с именованными параметрами в запросе.
Выполнение:
Когда метод репозитория вызывается, Spring Data JPA подставляет значения параметров метода в запрос, используя имена, указанные в @Param.
Уничтожение:
Аннотация не имеет явного жизненного цикла уничтожения, так как она используется только для привязки параметров.
Варианты настройки
Использование в JPQL:
Аннотация @Param используется для привязки параметров в JPQL-запросах:
@Query("SELECT u FROM User u WHERE u.email = :email AND u.age > :age")
User findByEmailAndAge(@Param("email") String email, @Param("age") int age);
Использование в нативных SQL-запросах:
Аннотация @Param также может использоваться в нативных SQL-запросах:
@Query(value = "SELECT * FROM users WHERE email = :email", nativeQuery = true)
User findByEmail(@Param("email") String email);
Использование с @Modifying:
Аннотация @Param может использоваться в методах, помеченных @Modifying, для выполнения модифицирующих операций:
@Modifying
@Query("UPDATE User u SET u.active = :active WHERE u.email = :email")
void updateUserStatus(@Param("email") String email, @Param("active") boolean active);
#Java #Training #Hard #Spring #SpringDataJPA #Param
Аннотация @Transactional
Аннотация @Transactional используется в Spring для управления транзакциями на уровне методов или классов. Она позволяет декларативно определять границы транзакций, их поведение и настройки. Аннотация находится в пакете org.springframework.transaction.annotation.
Параметры аннотации
value (необязательный):
Тип: String.
Значение по умолчанию: "".
Описание: Указывает имя менеджера транзакций (бина PlatformTransactionManager), который должен использоваться для управления транзакцией. Если не указано, используется менеджер транзакций по умолчанию.
Пример:
propagation (необязательный):
Тип: Propagation.
Значение по умолчанию: Propagation.REQUIRED.
Описание: Определяет поведение распространения транзакции.
Возможные значения:
REQUIRED: Использует текущую транзакцию, если она существует, или создает новую.
REQUIRES_NEW: Всегда создает новую транзакцию, приостанавливая текущую, если она существует.
SUPPORTS: Использует текущую транзакцию, если она существует, но не создает новую.
NOT_SUPPORTED: Выполняет метод вне транзакции, приостанавливая текущую, если она существует.
MANDATORY: Требует наличия активной транзакции, иначе выбрасывает исключение.
NEVER: Запрещает выполнение метода в транзакции, иначе выбрасывает исключение.
NESTED: Создает вложенную транзакцию, если текущая транзакция существует.
Пример:
isolation (необязательный):
Тип: Isolation.
Значение по умолчанию: Isolation.DEFAULT.
Описание: Определяет уровень изоляции транзакции.
Возможные значения:
DEFAULT: Использует уровень изоляции по умолчанию для базы данных.
READ_UNCOMMITTED: Позволяет читать незафиксированные изменения других транзакций.
READ_COMMITTED: Гарантирует, что читаются только зафиксированные данные.
REPEATABLE_READ: Гарантирует, что данные, прочитанные в транзакции, не изменятся другими транзакциями.
SERIALIZABLE: Самый строгий уровень изоляции, предотвращает любые конфликты.
Пример:
timeout (необязательный):
Тип: int.
Значение по умолчанию: -1 (без тайм-аута).
Описание: Указывает максимальное время выполнения транзакции в секундах. Если время превышено, транзакция откатывается.
Пример:
readOnly (необязательный)
Тип: boolean.
Значение по умолчанию: false.
Описание: Указывает, является ли транзакция только для чтения. Если true, это может оптимизировать выполнение запросов.
Пример:
rollbackFor (необязательный):
Тип: Class<? extends Throwable>[].
Значение по умолчанию: {}.
Описание: Указывает типы исключений, при которых транзакция должна быть откачена. По умолчанию откат происходит только для непроверяемых исключений (RuntimeException и его подклассов).
Пример:
noRollbackFor (необязательный):
Тип: Class<? extends Throwable>[].
Значение по умолчанию: {}.
Описание: Указывает типы исключений, при которых транзакция не должна быть откачена.
Пример:
#Java #Training #Hard #Spring #SpringDataJPA #Transactional
Аннотация @Transactional используется в Spring для управления транзакциями на уровне методов или классов. Она позволяет декларативно определять границы транзакций, их поведение и настройки. Аннотация находится в пакете org.springframework.transaction.annotation.
Параметры аннотации
value (необязательный):
Тип: String.
Значение по умолчанию: "".
Описание: Указывает имя менеджера транзакций (бина PlatformTransactionManager), который должен использоваться для управления транзакцией. Если не указано, используется менеджер транзакций по умолчанию.
Пример:
@Transactional("customTransactionManager")
public void performOperation() {
// Логика метода
}
propagation (необязательный):
Тип: Propagation.
Значение по умолчанию: Propagation.REQUIRED.
Описание: Определяет поведение распространения транзакции.
Возможные значения:
REQUIRED: Использует текущую транзакцию, если она существует, или создает новую.
REQUIRES_NEW: Всегда создает новую транзакцию, приостанавливая текущую, если она существует.
SUPPORTS: Использует текущую транзакцию, если она существует, но не создает новую.
NOT_SUPPORTED: Выполняет метод вне транзакции, приостанавливая текущую, если она существует.
MANDATORY: Требует наличия активной транзакции, иначе выбрасывает исключение.
NEVER: Запрещает выполнение метода в транзакции, иначе выбрасывает исключение.
NESTED: Создает вложенную транзакцию, если текущая транзакция существует.
Пример:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void performOperation() {
// Логика метода
}
isolation (необязательный):
Тип: Isolation.
Значение по умолчанию: Isolation.DEFAULT.
Описание: Определяет уровень изоляции транзакции.
Возможные значения:
DEFAULT: Использует уровень изоляции по умолчанию для базы данных.
READ_UNCOMMITTED: Позволяет читать незафиксированные изменения других транзакций.
READ_COMMITTED: Гарантирует, что читаются только зафиксированные данные.
REPEATABLE_READ: Гарантирует, что данные, прочитанные в транзакции, не изменятся другими транзакциями.
SERIALIZABLE: Самый строгий уровень изоляции, предотвращает любые конфликты.
Пример:
@Transactional(isolation = Isolation.READ_COMMITTED)
public void performOperation() {
// Логика метода
}
timeout (необязательный):
Тип: int.
Значение по умолчанию: -1 (без тайм-аута).
Описание: Указывает максимальное время выполнения транзакции в секундах. Если время превышено, транзакция откатывается.
Пример:
@Transactional(timeout = 10)
public void performOperation() {
// Логика метода
}
readOnly (необязательный)
Тип: boolean.
Значение по умолчанию: false.
Описание: Указывает, является ли транзакция только для чтения. Если true, это может оптимизировать выполнение запросов.
Пример:
@Transactional(readOnly = true)
public void readData() {
// Логика метода
}
rollbackFor (необязательный):
Тип: Class<? extends Throwable>[].
Значение по умолчанию: {}.
Описание: Указывает типы исключений, при которых транзакция должна быть откачена. По умолчанию откат происходит только для непроверяемых исключений (RuntimeException и его подклассов).
Пример:
@Transactional(rollbackFor = {CustomException.class})
public void performOperation() throws CustomException {
// Логика метода
}
noRollbackFor (необязательный):
Тип: Class<? extends Throwable>[].
Значение по умолчанию: {}.
Описание: Указывает типы исключений, при которых транзакция не должна быть откачена.
Пример:
@Transactional(noRollbackFor = {CustomException.class})
public void performOperation() throws CustomException {
// Логика метода
}
#Java #Training #Hard #Spring #SpringDataJPA #Transactional
Жизненный цикл аннотации
Инициализация:
Аннотация @Transactional обрабатывается во время инициализации Spring-контекста. Spring создает прокси-объекты для методов или классов, помеченных @Transactional.
Выполнение:
Когда метод вызывается, Spring проверяет настройки транзакции и начинает новую транзакцию (или использует существующую) в соответствии с параметрами propagation.
Если метод завершается успешно, транзакция фиксируется (commit). Если возникает исключение, транзакция откатывается (rollback), если это указано в параметрах.
Уничтожение:
После завершения метода транзакция завершается (фиксируется или откатывается), и ресурсы освобождаются.
Механизмы Spring и настройки Spring Boot
Spring AOP (Aspect-Oriented Programming):
Spring использует AOP для создания прокси-объектов, которые перехватывают вызовы методов, помеченных @Transactional, и управляют транзакциями.
PlatformTransactionManager:
Spring предоставляет интерфейс PlatformTransactionManager для управления транзакциями. Реализации включают DataSourceTransactionManager (для JDBC) и JpaTransactionManager (для JPA).
TransactionTemplate:
Для программного управления транзакциями можно использовать TransactionTemplate.
Варианты настройки
Использование нескольких менеджеров транзакций:
Если в приложении используется несколько источников данных, можно настроить несколько менеджеров транзакций и указывать их в параметре value аннотации @Transactional.
Программное управление транзакциями:
Для сложных сценариев можно использовать TransactionTemplate:
Использование вложенных транзакций:
Уровень изоляции NESTED позволяет создавать вложенные транзакции, которые могут быть откачены независимо от основной транзакции.
#Java #Training #Hard #Spring #SpringDataJPA #Transactional
Инициализация:
Аннотация @Transactional обрабатывается во время инициализации Spring-контекста. Spring создает прокси-объекты для методов или классов, помеченных @Transactional.
Выполнение:
Когда метод вызывается, Spring проверяет настройки транзакции и начинает новую транзакцию (или использует существующую) в соответствии с параметрами propagation.
Если метод завершается успешно, транзакция фиксируется (commit). Если возникает исключение, транзакция откатывается (rollback), если это указано в параметрах.
Уничтожение:
После завершения метода транзакция завершается (фиксируется или откатывается), и ресурсы освобождаются.
Механизмы Spring и настройки Spring Boot
Spring AOP (Aspect-Oriented Programming):
Spring использует AOP для создания прокси-объектов, которые перехватывают вызовы методов, помеченных @Transactional, и управляют транзакциями.
PlatformTransactionManager:
Spring предоставляет интерфейс PlatformTransactionManager для управления транзакциями. Реализации включают DataSourceTransactionManager (для JDBC) и JpaTransactionManager (для JPA).
TransactionTemplate:
Для программного управления транзакциями можно использовать TransactionTemplate.
Варианты настройки
Использование нескольких менеджеров транзакций:
Если в приложении используется несколько источников данных, можно настроить несколько менеджеров транзакций и указывать их в параметре value аннотации @Transactional.
Программное управление транзакциями:
Для сложных сценариев можно использовать TransactionTemplate:
@Autowired
private TransactionTemplate transactionTemplate;
public void performOperation() {
transactionTemplate.execute(status -> {
// Логика метода
return null;
});
}
Использование вложенных транзакций:
Уровень изоляции NESTED позволяет создавать вложенные транзакции, которые могут быть откачены независимо от основной транзакции.
#Java #Training #Hard #Spring #SpringDataJPA #Transactional
Аннотация @EnableJpaRepositories
Аннотация @EnableJpaRepositories используется в Spring Data JPA для активации репозиториев JPA в приложении. Она сканирует пакеты и регистрирует интерфейсы, расширяющие JpaRepository, как бины Spring. Аннотация находится в пакете org.springframework.data.jpa.repository.config.
Параметры аннотации
basePackages (необязательный):
Тип: String[].
Значение по умолчанию: {}.
Описание: Указывает пакеты, которые должны быть сканированы для поиска репозиториев JPA. Если не указано, используется пакет, в котором находится класс с аннотацией.
Пример:
basePackageClasses (необязательный):
Тип: Class<?>[].
Значение по умолчанию: {}.
Описание: Указывает классы, пакеты которых должны быть сканированы для поиска репозиториев JPA. Это альтернатива basePackages.
Пример:
includeFilters (необязательный):
Тип: ComponentScan.Filter[].
Значение по умолчанию: {}.
Описание: Указывает фильтры для включения определенных классов в сканирование репозиториев.
Пример:
excludeFilters (необязательный):
Тип: ComponentScan.Filter[].
Значение по умолчанию: {}.
Описание: Указывает фильтры для исключения определенных классов из сканирования репозиториев.
Пример:
repositoryImplementationPostfix (необязательный):
Тип: String.
Значение по умолчанию: "Impl".
Описание: Указывает постфикс для классов реализации репозиториев.
Пример:
entityManagerFactoryRef (необязательный):
Тип: String.
Значение по умолчанию: "entityManagerFactory".
Описание: Указывает имя бина EntityManagerFactory, который должен использоваться для репозиториев.
Пример:
transactionManagerRef (необязательный):
Тип: String.
Значение по умолчанию: "transactionManager".
Описание: Указывает имя бина PlatformTransactionManager, который должен использоваться для управления транзакциями репозиториев.
Пример:
considerNestedRepositories (необязательный):
Тип: boolean.
Значение по умолчанию: false.
Описание: Указывает, должны ли сканироваться вложенные репозитории (например, внутри других классов).
Пример:
enableDefaultTransactions (необязательный):
Тип: boolean.
Значение по умолчанию: true.
Описание: Указывает, должны ли методы репозиториев выполняться в транзакции по умолчанию.
Пример:
Жизненный цикл аннотации
Инициализация:
Аннотация @EnableJpaRepositories обрабатывается во время инициализации Spring-контекста. Spring Data JPA сканирует указанные пакеты и регистрирует интерфейсы репозиториев как бины.
Выполнение:
Когда приложение запущено, Spring Data JPA создает прокси-объекты для интерфейсов репозиториев, которые реализуют методы, определенные в JpaRepository и пользовательских запросах.
Уничтожение:
Аннотация не имеет явного жизненного цикла уничтожения, так как она используется только для конфигурации репозиториев.
#Java #Training #Hard #Spring #SpringDataJPA #EnableJpaRepositories
Аннотация @EnableJpaRepositories используется в Spring Data JPA для активации репозиториев JPA в приложении. Она сканирует пакеты и регистрирует интерфейсы, расширяющие JpaRepository, как бины Spring. Аннотация находится в пакете org.springframework.data.jpa.repository.config.
Параметры аннотации
basePackages (необязательный):
Тип: String[].
Значение по умолчанию: {}.
Описание: Указывает пакеты, которые должны быть сканированы для поиска репозиториев JPA. Если не указано, используется пакет, в котором находится класс с аннотацией.
Пример:
@EnableJpaRepositories(basePackages = "com.example.repositories")
basePackageClasses (необязательный):
Тип: Class<?>[].
Значение по умолчанию: {}.
Описание: Указывает классы, пакеты которых должны быть сканированы для поиска репозиториев JPA. Это альтернатива basePackages.
Пример:
@EnableJpaRepositories(basePackageClasses = {UserRepository.class, ProductRepository.class})
includeFilters (необязательный):
Тип: ComponentScan.Filter[].
Значение по умолчанию: {}.
Описание: Указывает фильтры для включения определенных классов в сканирование репозиториев.
Пример:
@EnableJpaRepositories(includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = CustomRepository.class))
excludeFilters (необязательный):
Тип: ComponentScan.Filter[].
Значение по умолчанию: {}.
Описание: Указывает фильтры для исключения определенных классов из сканирования репозиториев.
Пример:
@EnableJpaRepositories(excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = ExcludedRepository.class))
repositoryImplementationPostfix (необязательный):
Тип: String.
Значение по умолчанию: "Impl".
Описание: Указывает постфикс для классов реализации репозиториев.
Пример:
@EnableJpaRepositories(repositoryImplementationPostfix = "CustomImpl")
entityManagerFactoryRef (необязательный):
Тип: String.
Значение по умолчанию: "entityManagerFactory".
Описание: Указывает имя бина EntityManagerFactory, который должен использоваться для репозиториев.
Пример:
@EnableJpaRepositories(entityManagerFactoryRef = "customEntityManagerFactory")
transactionManagerRef (необязательный):
Тип: String.
Значение по умолчанию: "transactionManager".
Описание: Указывает имя бина PlatformTransactionManager, который должен использоваться для управления транзакциями репозиториев.
Пример:
@EnableJpaRepositories(transactionManagerRef = "customTransactionManager")
considerNestedRepositories (необязательный):
Тип: boolean.
Значение по умолчанию: false.
Описание: Указывает, должны ли сканироваться вложенные репозитории (например, внутри других классов).
Пример:
@EnableJpaRepositories(considerNestedRepositories = true)
enableDefaultTransactions (необязательный):
Тип: boolean.
Значение по умолчанию: true.
Описание: Указывает, должны ли методы репозиториев выполняться в транзакции по умолчанию.
Пример:
@EnableJpaRepositories(enableDefaultTransactions = false)
Жизненный цикл аннотации
Инициализация:
Аннотация @EnableJpaRepositories обрабатывается во время инициализации Spring-контекста. Spring Data JPA сканирует указанные пакеты и регистрирует интерфейсы репозиториев как бины.
Выполнение:
Когда приложение запущено, Spring Data JPA создает прокси-объекты для интерфейсов репозиториев, которые реализуют методы, определенные в JpaRepository и пользовательских запросах.
Уничтожение:
Аннотация не имеет явного жизненного цикла уничтожения, так как она используется только для конфигурации репозиториев.
#Java #Training #Hard #Spring #SpringDataJPA #EnableJpaRepositories
Аннотация @EntityGraph
Аннотация @EntityGraph используется в Spring Data JPA для управления стратегией загрузки связанных сущностей (например, EAGER или LAZY). Она позволяет динамически определять, какие ассоциации должны быть загружены вместе с основной сущностью, что помогает избежать проблемы N+1 запросов. Аннотация находится в пакете org.springframework.data.jpa.repository.EntityGraph.
Параметры аннотации
value (необязательный):
Тип: String.
Значение по умолчанию: "".
Описание: Указывает имя именованного графа сущности (Named EntityGraph), который должен быть использован. Именованный граф должен быть определен в сущности с помощью аннотации @NamedEntityGraph.
Пример:
type (необязательный):
Тип: EntityGraphType.
Значение по умолчанию: EntityGraphType.FETCH.
Описание: Определяет тип графа сущности.
Возможные значения:
FETCH: Загружает только указанные ассоциации.
LOAD: Загружает указанные ассоциации, а остальные загружает в соответствии с их стратегией загрузки (например, LAZY или EAGER).
Пример:
attributePaths (необязательный):
Тип: String[].
Значение по умолчанию: {}.
Описание: Указывает пути к атрибутам сущности, которые должны быть загружены. Это альтернатива использованию именованного графа.
Пример:
Жизненный цикл аннотации
Инициализация:
Аннотация @EntityGraph обрабатывается во время инициализации Spring-контекста. Spring Data JPA анализирует методы репозитория и настраивает графы сущностей.
Выполнение:
Когда метод репозитория вызывается, Spring Data JPA применяет указанный граф сущности к запросу, загружая указанные ассоциации.
Уничтожение:
Аннотация не имеет явного жизненного цикла уничтожения, так как она используется только для конфигурации загрузки сущностей.
Варианты настройки
Использование именованных графов:
Именованные графы сущностей можно определить в сущности с помощью аннотации @NamedEntityGraph:
Использование динамических графов:
Динамические графы можно указать с помощью параметра attributePaths:
Комбинирование с @Query:
Аннотация @EntityGraph может использоваться вместе с @Query для более сложных запросов:
Использование нескольких графов:
Можно указать несколько графов сущностей, если это поддерживается JPA-провайдером.
#Java #Training #Hard #Spring #SpringDataJPA #EntityGraph
Аннотация @EntityGraph используется в Spring Data JPA для управления стратегией загрузки связанных сущностей (например, EAGER или LAZY). Она позволяет динамически определять, какие ассоциации должны быть загружены вместе с основной сущностью, что помогает избежать проблемы N+1 запросов. Аннотация находится в пакете org.springframework.data.jpa.repository.EntityGraph.
Параметры аннотации
value (необязательный):
Тип: String.
Значение по умолчанию: "".
Описание: Указывает имя именованного графа сущности (Named EntityGraph), который должен быть использован. Именованный граф должен быть определен в сущности с помощью аннотации @NamedEntityGraph.
Пример:
@EntityGraph(value = "User.withAddress")
User findById(Long id);
type (необязательный):
Тип: EntityGraphType.
Значение по умолчанию: EntityGraphType.FETCH.
Описание: Определяет тип графа сущности.
Возможные значения:
FETCH: Загружает только указанные ассоциации.
LOAD: Загружает указанные ассоциации, а остальные загружает в соответствии с их стратегией загрузки (например, LAZY или EAGER).
Пример:
@EntityGraph(type = EntityGraphType.LOAD)
User findById(Long id);
attributePaths (необязательный):
Тип: String[].
Значение по умолчанию: {}.
Описание: Указывает пути к атрибутам сущности, которые должны быть загружены. Это альтернатива использованию именованного графа.
Пример:
@EntityGraph(attributePaths = {"address", "orders"})
User findById(Long id);
Жизненный цикл аннотации
Инициализация:
Аннотация @EntityGraph обрабатывается во время инициализации Spring-контекста. Spring Data JPA анализирует методы репозитория и настраивает графы сущностей.
Выполнение:
Когда метод репозитория вызывается, Spring Data JPA применяет указанный граф сущности к запросу, загружая указанные ассоциации.
Уничтожение:
Аннотация не имеет явного жизненного цикла уничтожения, так как она используется только для конфигурации загрузки сущностей.
Варианты настройки
Использование именованных графов:
Именованные графы сущностей можно определить в сущности с помощью аннотации @NamedEntityGraph:
@Entity
@NamedEntityGraph(name = "User.withAddress", attributeNodes = @NamedAttributeNode("address"))
public class User {
// Поля и методы
}
Использование динамических графов:
Динамические графы можно указать с помощью параметра attributePaths:
@EntityGraph(attributePaths = {"address", "orders"})
User findById(Long id);
Комбинирование с @Query:
Аннотация @EntityGraph может использоваться вместе с @Query для более сложных запросов:
@EntityGraph(attributePaths = {"address"})
@Query("SELECT u FROM User u WHERE u.email = :email")
User findByEmail(@Param("email") String email);
Использование нескольких графов:
Можно указать несколько графов сущностей, если это поддерживается JPA-провайдером.
#Java #Training #Hard #Spring #SpringDataJPA #EntityGraph
Аннотация @Lock
Аннотация @Lock используется в Spring Data JPA для указания типа блокировки, которая должна быть применена при выполнении запроса. Это полезно для управления параллельным доступом к данным и предотвращения проблем, таких как потерянные обновления или грязное чтение. Аннотация находится в пакете org.springframework.data.jpa.repository.Lock.
Параметры аннотации
value (обязательный):
Тип: LockModeType.
Описание: Указывает тип блокировки, который должен быть применен к запросу.
Возможные значения:
LockModeType.PESSIMISTIC_READ: Пессимистическая блокировка для чтения. Позволяет другим транзакциям читать данные, но не изменять их.
LockModeType.PESSIMISTIC_WRITE: Пессимистическая блокировка для записи. Блокирует данные для чтения и записи другими транзакциями.
LockModeType.PESSIMISTIC_FORCE_INCREMENT: Пессимистическая блокировка с принудительным увеличением версии (используется с оптимистичной блокировкой).
LockModeType.OPTIMISTIC: Оптимистическая блокировка. Проверяет версию сущности при фиксации транзакции.
LockModeType.OPTIMISTIC_FORCE_INCREMENT: Оптимистическая блокировка с принудительным увеличением версии.
LockModeType.NONE: Отсутствие блокировки (по умолчанию).
Пример:
Жизненный цикл аннотации
Инициализация:
Аннотация @Lock обрабатывается во время инициализации Spring-контекста. Spring Data JPA анализирует методы репозитория и настраивает блокировки.
Выполнение:
Когда метод репозитория вызывается, Spring Data JPA применяет указанную блокировку к запросу. Блокировка сохраняется до завершения транзакции.
Уничтожение:
Аннотация не имеет явного жизненного цикла уничтожения, так как она используется только для конфигурации блокировок.
Варианты настройки
Использование пессимистических блокировок:
Пессимистические блокировки полезны для предотвращения конфликтов при параллельном доступе к данным:
Использование оптимистических блокировок:
Оптимистические блокировки полезны для предотвращения конфликтов при обновлении данных:
Комбинирование с @Query:
Аннотация @Lock может использоваться вместе с @Query для более сложных запросов:
Использование с @Transactional:
Методы с @Lock должны выполняться в транзакции, чтобы блокировка сохранялась до завершения транзакции:
#Java #Training #Hard #Spring #SpringDataJPA #Lock
Аннотация @Lock используется в Spring Data JPA для указания типа блокировки, которая должна быть применена при выполнении запроса. Это полезно для управления параллельным доступом к данным и предотвращения проблем, таких как потерянные обновления или грязное чтение. Аннотация находится в пакете org.springframework.data.jpa.repository.Lock.
Параметры аннотации
value (обязательный):
Тип: LockModeType.
Описание: Указывает тип блокировки, который должен быть применен к запросу.
Возможные значения:
LockModeType.PESSIMISTIC_READ: Пессимистическая блокировка для чтения. Позволяет другим транзакциям читать данные, но не изменять их.
LockModeType.PESSIMISTIC_WRITE: Пессимистическая блокировка для записи. Блокирует данные для чтения и записи другими транзакциями.
LockModeType.PESSIMISTIC_FORCE_INCREMENT: Пессимистическая блокировка с принудительным увеличением версии (используется с оптимистичной блокировкой).
LockModeType.OPTIMISTIC: Оптимистическая блокировка. Проверяет версию сущности при фиксации транзакции.
LockModeType.OPTIMISTIC_FORCE_INCREMENT: Оптимистическая блокировка с принудительным увеличением версии.
LockModeType.NONE: Отсутствие блокировки (по умолчанию).
Пример:
@Lock(LockModeType.PESSIMISTIC_WRITE)
User findById(Long id);
Жизненный цикл аннотации
Инициализация:
Аннотация @Lock обрабатывается во время инициализации Spring-контекста. Spring Data JPA анализирует методы репозитория и настраивает блокировки.
Выполнение:
Когда метод репозитория вызывается, Spring Data JPA применяет указанную блокировку к запросу. Блокировка сохраняется до завершения транзакции.
Уничтожение:
Аннотация не имеет явного жизненного цикла уничтожения, так как она используется только для конфигурации блокировок.
Варианты настройки
Использование пессимистических блокировок:
Пессимистические блокировки полезны для предотвращения конфликтов при параллельном доступе к данным:
@Lock(LockModeType.PESSIMISTIC_WRITE)
User findById(Long id);
Использование оптимистических блокировок:
Оптимистические блокировки полезны для предотвращения конфликтов при обновлении данных:
@Lock(LockModeType.OPTIMISTIC)
User findById(Long id);
Комбинирование с @Query:
Аннотация @Lock может использоваться вместе с @Query для более сложных запросов:
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("SELECT u FROM User u WHERE u.email = :email")
User findByEmail(@Param("email") String email);
Использование с @Transactional:
Методы с @Lock должны выполняться в транзакции, чтобы блокировка сохранялась до завершения транзакции:
@Transactional
@Lock(LockModeType.PESSIMISTIC_WRITE)
User findById(Long id);
#Java #Training #Hard #Spring #SpringDataJPA #Lock
Аннотация @Procedure
Аннотация @Procedure используется в Spring Data JPA для вызова хранимых процедур и функций, определенных в базе данных. Она позволяет интегрировать вызовы хранимых процедур в репозиторные интерфейсы Spring Data. Аннотация находится в пакете org.springframework.data.jpa.repository.query.
Параметры аннотации
value (необязательный):
Тип: String.
Значение по умолчанию: "".
Описание: Указывает имя хранимой процедуры или функции в базе данных. Если не указано, используется имя метода.
Пример:
procedureName (необязательный):
Тип: String.
Значение по умолчанию: "".
Описание: Альтернативное имя для параметра value. Указывает имя хранимой процедуры или функции.
Пример:
outputParameterName (необязательный):
Тип: String.
Значение по умолчанию: "".
Описание: Указывает имя выходного параметра, если хранимая процедура возвращает значение через выходной параметр.
Пример:
Жизненный цикл аннотации
Инициализация:
Аннотация @Procedure обрабатывается во время инициализации Spring-контекста. Spring Data JPA анализирует методы репозитория и настраивает вызовы хранимых процедур.
Выполнение:
Когда метод репозитория вызывается, Spring Data JPA выполняет указанную хранимую процедуру или функцию через JPA-провайдер (например, Hibernate).
Уничтожение:
Аннотация не имеет явного жизненного цикла уничтожения, так как она используется только для конфигурации вызовов хранимых процедур.
Варианты настройки
Использование именованных хранимых процедур:
Именованные хранимые процедуры можно определить в сущности с помощью аннотации @NamedStoredProcedureQuery:
Использование выходных параметров:
Если хранимая процедура возвращает значение через выходной параметр, можно указать его имя с помощью параметра outputParameterName:
Использование с @Query:
Аннотация @Procedure может использоваться вместе с @Query для более сложных сценариев:
Использование с @Transactional:
Методы с @Procedure должны выполняться в транзакции, чтобы гарантировать атомарность операций:
#Java #Training #Hard #Spring #SpringDataJPA #Procedure
Аннотация @Procedure используется в Spring Data JPA для вызова хранимых процедур и функций, определенных в базе данных. Она позволяет интегрировать вызовы хранимых процедур в репозиторные интерфейсы Spring Data. Аннотация находится в пакете org.springframework.data.jpa.repository.query.
Параметры аннотации
value (необязательный):
Тип: String.
Значение по умолчанию: "".
Описание: Указывает имя хранимой процедуры или функции в базе данных. Если не указано, используется имя метода.
Пример:
@Procedure("calculate_discount")
BigDecimal calculateDiscount(@Param("orderId") Long orderId);
procedureName (необязательный):
Тип: String.
Значение по умолчанию: "".
Описание: Альтернативное имя для параметра value. Указывает имя хранимой процедуры или функции.
Пример:
@Procedure(procedureName = "calculate_discount")
BigDecimal calculateDiscount(@Param("orderId") Long orderId);
outputParameterName (необязательный):
Тип: String.
Значение по умолчанию: "".
Описание: Указывает имя выходного параметра, если хранимая процедура возвращает значение через выходной параметр.
Пример:
@Procedure(outputParameterName = "discount")
BigDecimal calculateDiscount(@Param("orderId") Long orderId);
Жизненный цикл аннотации
Инициализация:
Аннотация @Procedure обрабатывается во время инициализации Spring-контекста. Spring Data JPA анализирует методы репозитория и настраивает вызовы хранимых процедур.
Выполнение:
Когда метод репозитория вызывается, Spring Data JPA выполняет указанную хранимую процедуру или функцию через JPA-провайдер (например, Hibernate).
Уничтожение:
Аннотация не имеет явного жизненного цикла уничтожения, так как она используется только для конфигурации вызовов хранимых процедур.
Варианты настройки
Использование именованных хранимых процедур:
Именованные хранимые процедуры можно определить в сущности с помощью аннотации @NamedStoredProcedureQuery:
@Entity
@NamedStoredProcedureQuery(
name = "calculate_discount",
procedureName = "calculate_discount",
parameters = {
@StoredProcedureParameter(mode = ParameterMode.IN, name = "orderId", type = Long.class),
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "discount", type = BigDecimal.class)
}
)
public class Order {
// Поля и методы
}
Использование выходных параметров:
Если хранимая процедура возвращает значение через выходной параметр, можно указать его имя с помощью параметра outputParameterName:
@Procedure(outputParameterName = "discount")
BigDecimal calculateDiscount(@Param("orderId") Long orderId);
Использование с @Query:
Аннотация @Procedure может использоваться вместе с @Query для более сложных сценариев:
@Procedure
@Query(value = "CALL calculate_discount(:orderId, :discount)", nativeQuery = true)
BigDecimal calculateDiscount(@Param("orderId") Long orderId, @Param("discount") BigDecimal discount);
Использование с @Transactional:
Методы с @Procedure должны выполняться в транзакции, чтобы гарантировать атомарность операций:
@Transactional
@Procedure("calculate_discount")
BigDecimal calculateDiscount(@Param("orderId") Long orderId);
#Java #Training #Hard #Spring #SpringDataJPA #Procedure
Аннотация @IdClass
Аннотация @IdClass используется в JPA (Java Persistence API) для указания класса, который представляет составной первичный ключ сущности. Она применяется, когда сущность имеет несколько полей, которые вместе образуют уникальный идентификатор (составной ключ). Аннотация находится в пакете javax.persistence.
Параметры аннотации
value (обязательный):
Тип: Class<?>.
Описание: Указывает класс, который представляет составной первичный ключ. Этот класс должен быть сериализуемым, иметь конструктор по умолчанию и переопределять методы equals() и hashCode().
Пример:
Жизненный цикл аннотации
Инициализация:
Аннотация @IdClass обрабатывается во время инициализации JPA-провайдера (например, Hibernate). JPA-провайдер анализирует сущность и создает метаданные для составного ключа.
Выполнение:
Когда сущность сохраняется, обновляется или извлекается из базы данных, JPA-провайдер использует класс, указанный в @IdClass, для работы с составным ключом.
Уничтожение:
Аннотация не имеет явного жизненного цикла уничтожения, так как она используется только для конфигурации составного ключа.
Варианты настройки
Использование составного ключа:
Класс, представляющий составной ключ, должен быть сериализуемым, иметь конструктор по умолчанию и переопределять методы equals() и hashCode():
Использование с @Embeddable:
Вместо @IdClass можно использовать аннотацию @Embeddable для определения составного ключа:
Использование с репозиториями:
Репозитории Spring Data JPA могут работать с сущностями, имеющими составные ключи:
#Java #Training #Hard #Spring #SpringDataJPA #IdClass
Аннотация @IdClass используется в JPA (Java Persistence API) для указания класса, который представляет составной первичный ключ сущности. Она применяется, когда сущность имеет несколько полей, которые вместе образуют уникальный идентификатор (составной ключ). Аннотация находится в пакете javax.persistence.
Параметры аннотации
value (обязательный):
Тип: Class<?>.
Описание: Указывает класс, который представляет составной первичный ключ. Этот класс должен быть сериализуемым, иметь конструктор по умолчанию и переопределять методы equals() и hashCode().
Пример:
@IdClass(UserId.class)
public class User {
@Id
private Long departmentId;
@Id
private Long userId;
// Остальные поля и методы
}
Жизненный цикл аннотации
Инициализация:
Аннотация @IdClass обрабатывается во время инициализации JPA-провайдера (например, Hibernate). JPA-провайдер анализирует сущность и создает метаданные для составного ключа.
Выполнение:
Когда сущность сохраняется, обновляется или извлекается из базы данных, JPA-провайдер использует класс, указанный в @IdClass, для работы с составным ключом.
Уничтожение:
Аннотация не имеет явного жизненного цикла уничтожения, так как она используется только для конфигурации составного ключа.
Варианты настройки
Использование составного ключа:
Класс, представляющий составной ключ, должен быть сериализуемым, иметь конструктор по умолчанию и переопределять методы equals() и hashCode():
public class UserId implements Serializable {
private Long departmentId;
private Long userId;
// Конструктор по умолчанию
public UserId() {}
// Конструктор с параметрами
public UserId(Long departmentId, Long userId) {
this.departmentId = departmentId;
this.userId = userId;
}
// Геттеры и сеттеры
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserId userId1 = (UserId) o;
return Objects.equals(departmentId, userId1.departmentId) &&
Objects.equals(userId, userId1.userId);
}
@Override
public int hashCode() {
return Objects.hash(departmentId, userId);
}
}
Использование с @Embeddable:
Вместо @IdClass можно использовать аннотацию @Embeddable для определения составного ключа:
@Embeddable
public class UserId implements Serializable {
private Long departmentId;
private Long userId;
// Конструктор по умолчанию, геттеры, сеттеры, equals, hashCode
}
@Entity
public class User {
@EmbeddedId
private UserId id;
// Остальные поля и методы
}
Использование с репозиториями:
Репозитории Spring Data JPA могут работать с сущностями, имеющими составные ключи:
public interface UserRepository extends JpaRepository<User, UserId> {
// Методы репозитория
}
#Java #Training #Hard #Spring #SpringDataJPA #IdClass
Аннотация @MapsId
Аннотация @MapsId используется в JPA (Java Persistence API) для указания, что внешний ключ сущности также является её первичным ключом. Это полезно при работе с отношениями "один к одному" или "многие к одному", где дочерняя сущность использует первичный ключ родительской сущности в качестве своего собственного первичного ключа. Аннотация находится в пакете javax.persistence.
Параметры аннотации
value (необязательный):
Тип: String.
Значение по умолчанию: "".
Описание: Указывает имя атрибута сущности, который является первичным ключом. Если не указано, используется первичный ключ родительской сущности.
Пример:
Жизненный цикл аннотации
Инициализация:
Аннотация @MapsId обрабатывается во время инициализации JPA-провайдера (например, Hibernate). JPA-провайдер анализирует сущность и создает метаданные для связи с родительской сущностью.
Выполнение:
Когда сущность сохраняется, обновляется или извлекается из базы данных, JPA-провайдер использует первичный ключ родительской сущности в качестве первичного ключа дочерней сущности.
Уничтожение:
Аннотация не имеет явного жизненного цикла уничтожения, так как она используется только для конфигурации связи с родительской сущностью.
Варианты настройки
Использование с @OneToOne:
Аннотация @MapsId часто используется с отношением "один к одному":
Использование с @ManyToOne:
Аннотация @MapsId также может использоваться с отношением "многие к одному":
Использование с составными ключами:
Аннотация @MapsId может использоваться с составными ключами, если родительская сущность имеет составной ключ:
Использование с репозиториями:
Репозитории Spring Data JPA могут работать с сущностями, имеющими аннотацию @MapsId:
#Java #Training #Hard #Spring #SpringDataJPA #MapsId
Аннотация @MapsId используется в JPA (Java Persistence API) для указания, что внешний ключ сущности также является её первичным ключом. Это полезно при работе с отношениями "один к одному" или "многие к одному", где дочерняя сущность использует первичный ключ родительской сущности в качестве своего собственного первичного ключа. Аннотация находится в пакете javax.persistence.
Параметры аннотации
value (необязательный):
Тип: String.
Значение по умолчанию: "".
Описание: Указывает имя атрибута сущности, который является первичным ключом. Если не указано, используется первичный ключ родительской сущности.
Пример:
@MapsId("userId")
@OneToOne
@JoinColumn(name = "user_id")
private User user;
Жизненный цикл аннотации
Инициализация:
Аннотация @MapsId обрабатывается во время инициализации JPA-провайдера (например, Hibernate). JPA-провайдер анализирует сущность и создает метаданные для связи с родительской сущностью.
Выполнение:
Когда сущность сохраняется, обновляется или извлекается из базы данных, JPA-провайдер использует первичный ключ родительской сущности в качестве первичного ключа дочерней сущности.
Уничтожение:
Аннотация не имеет явного жизненного цикла уничтожения, так как она используется только для конфигурации связи с родительской сущностью.
Варианты настройки
Использование с @OneToOne:
Аннотация @MapsId часто используется с отношением "один к одному":
@Entity
public class UserProfile {
@Id
private Long userId;
@MapsId
@OneToOne
@JoinColumn(name = "user_id")
private User user;
// Остальные поля и методы
}
Использование с @ManyToOne:
Аннотация @MapsId также может использоваться с отношением "многие к одному":
@Entity
public class Order {
@Id
private Long orderId;
@MapsId("userId")
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
// Остальные поля и методы
}
Использование с составными ключами:
Аннотация @MapsId может использоваться с составными ключами, если родительская сущность имеет составной ключ:
@Entity
public class UserProfile {
@EmbeddedId
private UserProfileId id;
@MapsId("userId")
@ManyToOne
@JoinColumns({
@JoinColumn(name = "department_id", referencedColumnName = "departmentId"),
@JoinColumn(name = "user_id", referencedColumnName = "userId")
})
private User user;
// Остальные поля и методы
}
Использование с репозиториями:
Репозитории Spring Data JPA могут работать с сущностями, имеющими аннотацию @MapsId:
public interface UserProfileRepository extends JpaRepository<UserProfile, Long> {
// Методы репозитория
}
#Java #Training #Hard #Spring #SpringDataJPA #MapsId
Аннотация @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
Аннотация @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
Аннотация @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
Аннотация @PersistenceContext
Аннотация @PersistenceContext используется для внедрения (inject) контейнера управляемых JPA-сущностей (EntityManager) в Spring-приложение. Она принадлежит к спецификации Jakarta Persistence API (JPA) и находится в пакете jakarta.persistence.
Spring автоматически управляет жизненным циклом EntityManager, обеспечивая корректное открытие и закрытие сессий, а также интеграцию с транзакциями.
Параметры аннотации
name (необязательный)
Тип: String
Описание: Имя единицы персистентности (persistence-unit), если их несколько в persistence.xml.
Пример:
unitName (необязательный)
Тип: String
Описание: Альтернатива name, явно указывает имя persistence-unit.
Пример:
type (необязательный)
Тип: PersistenceContextType (TRANSACTION или EXTENDED)
Значение по умолчанию: TRANSACTION
Описание:
TRANSACTION (по умолчанию): EntityManager привязан к текущей транзакции и закрывается после её завершения.
EXTENDED: EntityManager живет дольше транзакции (используется в Stateful-бинах, например, в JSF).
Пример:
properties (необязательный)
Тип: Map<String, Object>
Описание: Дополнительные свойства для настройки EntityManager (например, hibernate.jdbc.batch_size).
Пример:
Жизненный цикл @PersistenceContext
Инициализация
При старте Spring создает прокси для EntityManager, который делегирует вызовы реальному EntityManager только внутри транзакции.
Если используется EXTENDED, EntityManager сохраняет состояние между транзакциями.
Работа в транзакции
В режиме TRANSACTION (по умолчанию) EntityManager автоматически открывается при старте транзакции (@Transactional) и закрывается после её завершения.
Уничтожение
В режиме TRANSACTION EntityManager закрывается после завершения транзакции.
В режиме EXTENDED EntityManager живет до уничтожения бина (например, при завершении HTTP-сессии в веб-приложении).
Механизмы Spring и настройки Spring Boot
1. Как Spring Boot настраивает EntityManager?
Spring Boot автоматически создает EntityManagerFactory на основе:
Настроек DataSource (из application.properties).
JPA-провайдера (Hibernate по умолчанию).
2. Альтернативные варианты настройки
Несколько источников данных:
Если нужно несколько EntityManager, можно определить несколько @Bean в конфигурации:
Ручное управление транзакциями:
Можно использовать EntityManager без @Transactional, но тогда нужно вручную вызывать em.getTransaction().begin() и commit().
Аннотация @PersistenceUnit
Аннотация @PersistenceUnit используется для внедрения EntityManagerFactory (а не самого EntityManager). Полезна, когда требуется создавать EntityManager вручную.
Параметры
unitName (необязательный) – имя persistence-unit (если их несколько).
Пример использования
Когда использовать @PersistenceUnit вместо @PersistenceContext?
Если нужно полное управление жизненным циклом EntityManager (например, в batch-обработке).
Если требуется несколько EntityManager в одном методе.
#Java #Training #Hard #Spring #SpringDataJPA #PersistenceUnit #PersistenceContext
Аннотация @PersistenceContext используется для внедрения (inject) контейнера управляемых JPA-сущностей (EntityManager) в Spring-приложение. Она принадлежит к спецификации Jakarta Persistence API (JPA) и находится в пакете jakarta.persistence.
Spring автоматически управляет жизненным циклом EntityManager, обеспечивая корректное открытие и закрытие сессий, а также интеграцию с транзакциями.
Параметры аннотации
name (необязательный)
Тип: String
Описание: Имя единицы персистентности (persistence-unit), если их несколько в persistence.xml.
Пример:
@PersistenceContext(name = "myPersistenceUnit")
private EntityManager entityManager;
unitName (необязательный)
Тип: String
Описание: Альтернатива name, явно указывает имя persistence-unit.
Пример:
@PersistenceContext(unitName = "myPersistenceUnit")
private EntityManager entityManager;
type (необязательный)
Тип: PersistenceContextType (TRANSACTION или EXTENDED)
Значение по умолчанию: TRANSACTION
Описание:
TRANSACTION (по умолчанию): EntityManager привязан к текущей транзакции и закрывается после её завершения.
EXTENDED: EntityManager живет дольше транзакции (используется в Stateful-бинах, например, в JSF).
Пример:
@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager entityManager;
properties (необязательный)
Тип: Map<String, Object>
Описание: Дополнительные свойства для настройки EntityManager (например, hibernate.jdbc.batch_size).
Пример:
@PersistenceContext(properties = {
@PersistenceProperty(name = "hibernate.jdbc.batch_size", value = "20")
})
private EntityManager entityManager;
Жизненный цикл @PersistenceContext
Инициализация
При старте Spring создает прокси для EntityManager, который делегирует вызовы реальному EntityManager только внутри транзакции.
Если используется EXTENDED, EntityManager сохраняет состояние между транзакциями.
Работа в транзакции
В режиме TRANSACTION (по умолчанию) EntityManager автоматически открывается при старте транзакции (@Transactional) и закрывается после её завершения.
Уничтожение
В режиме TRANSACTION EntityManager закрывается после завершения транзакции.
В режиме EXTENDED EntityManager живет до уничтожения бина (например, при завершении HTTP-сессии в веб-приложении).
Механизмы Spring и настройки Spring Boot
1. Как Spring Boot настраивает EntityManager?
Spring Boot автоматически создает EntityManagerFactory на основе:
Настроек DataSource (из application.properties).
JPA-провайдера (Hibernate по умолчанию).
2. Альтернативные варианты настройки
Несколько источников данных:
Если нужно несколько EntityManager, можно определить несколько @Bean в конфигурации:
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan("com.example.domain");
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
return em;
}
Ручное управление транзакциями:
Можно использовать EntityManager без @Transactional, но тогда нужно вручную вызывать em.getTransaction().begin() и commit().
Аннотация @PersistenceUnit
Аннотация @PersistenceUnit используется для внедрения EntityManagerFactory (а не самого EntityManager). Полезна, когда требуется создавать EntityManager вручную.
Параметры
unitName (необязательный) – имя persistence-unit (если их несколько).
Пример использования
@PersistenceUnit
private EntityManagerFactory emf;
public void someMethod() {
EntityManager em = emf.createEntityManager();
try {
em.getTransaction().begin();
// ... операции с БД ...
em.getTransaction().commit();
} finally {
em.close();
}
}
Когда использовать @PersistenceUnit вместо @PersistenceContext?
Если нужно полное управление жизненным циклом EntityManager (например, в batch-обработке).
Если требуется несколько EntityManager в одном методе.
#Java #Training #Hard #Spring #SpringDataJPA #PersistenceUnit #PersistenceContext
Аннотация @EnableJpaAuditing
Аннотация @EnableJpaAuditing активирует поддержку аудита сущностей JPA в Spring Data. Она позволяет автоматически отслеживать изменения в сущностях, такие как:
Кто создал или изменил запись (createdBy, lastModifiedBy).
Когда запись была создана или изменена (createdDate, lastModifiedDate).
Параметры аннотации
auditorAwareRef (необязательный)
Тип: String
Описание: Указывает имя бина, реализующего интерфейс AuditorAware<T>. Этот бин предоставляет информацию о текущем пользователе (например, из Spring Security).
Пример:
dateTimeProviderRef (необязательный)
Тип: String
Описание: Указывает имя бина, реализующего DateTimeProvider. Позволяет кастомизировать логику получения текущей даты/времени (например, для тестов).
Пример:
setDates (необязательный)
Тип: boolean
Значение по умолчанию: true
Описание: Если false, автоматическое обновление полей createdDate и lastModifiedDate отключается.
modifyOnCreate (необязательный)
Тип: boolean
Значение по умолчанию: true
Описание: Если false, поле lastModifiedDate не обновляется при создании сущности (только createdDate).
Жизненный цикл аудита
Инициализация
При старте приложения Spring ищет классы с @EnableJpaAuditing и регистрирует AuditingEntityListener.
Если указан auditorAwareRef, Spring внедряет соответствующий бин.
Сохранение/обновление сущности
Перед вставкой (@PrePersist) автоматически заполняются:
createdBy и createdDate (если поддерживается).
Перед обновлением (@PreUpdate) заполняются:
lastModifiedBy и lastModifiedDate.
Уничтожение
Аудит не влияет на удаление сущностей, но можно добавить @PreRemove логику вручную.
Механизмы Spring и настройки Spring Boot
1. Как работает аудит в Spring Data JPA?
AuditingEntityListener – JPA-колбек, который обрабатывает события @PrePersist и @PreUpdate.
AuditorAware – интерфейс для получения информации о текущем пользователе.
@CreatedDate, @LastModifiedDate, @CreatedBy, @LastModifiedBy – аннотации для полей сущности.
2. Настройка сущности
3. Конфигурация Spring Boot
Если используется Spring Boot, можно не указывать @EnableJpaAuditing вручную, если:
Есть бин AuditorAware.
Включен spring.data.jpa.repositories.bootstrap-mode=default (по умолчанию).
Пример application.properties:
4. Интеграция с Spring Security
Если приложение использует Spring Security, AuditorAware может возвращать текущего пользователя:
Варианты настройки
Отключение аудита для отдельных полей
Не аннотировать поле @CreatedBy, если оно не нужно.
Кастомные даты
Реализовать DateTimeProvider, если требуется использовать не Instant.now(), а другую временную зону.
Аудит без Spring Security
Можно возвращать фиксированное значение (например, "system"):
#Java #Training #Hard #Spring #SpringDataJPA #EnableJpaAuditing
Аннотация @EnableJpaAuditing активирует поддержку аудита сущностей JPA в Spring Data. Она позволяет автоматически отслеживать изменения в сущностях, такие как:
Кто создал или изменил запись (createdBy, lastModifiedBy).
Когда запись была создана или изменена (createdDate, lastModifiedDate).
Параметры аннотации
auditorAwareRef (необязательный)
Тип: String
Описание: Указывает имя бина, реализующего интерфейс AuditorAware<T>. Этот бин предоставляет информацию о текущем пользователе (например, из Spring Security).
Пример:
@EnableJpaAuditing(auditorAwareRef = "auditorProvider")
@Configuration
public class JpaConfig {
@Bean
public AuditorAware<String> auditorProvider() {
return () -> Optional.of("admin"); // Возвращает текущего пользователя
}
}
dateTimeProviderRef (необязательный)
Тип: String
Описание: Указывает имя бина, реализующего DateTimeProvider. Позволяет кастомизировать логику получения текущей даты/времени (например, для тестов).
Пример:
@EnableJpaAuditing(dateTimeProviderRef = "customDateTimeProvider")
@Configuration
public class JpaConfig {
@Bean
public DateTimeProvider customDateTimeProvider() {
return () -> Optional.of(Instant.now());
}
}
setDates (необязательный)
Тип: boolean
Значение по умолчанию: true
Описание: Если false, автоматическое обновление полей createdDate и lastModifiedDate отключается.
modifyOnCreate (необязательный)
Тип: boolean
Значение по умолчанию: true
Описание: Если false, поле lastModifiedDate не обновляется при создании сущности (только createdDate).
Жизненный цикл аудита
Инициализация
При старте приложения Spring ищет классы с @EnableJpaAuditing и регистрирует AuditingEntityListener.
Если указан auditorAwareRef, Spring внедряет соответствующий бин.
Сохранение/обновление сущности
Перед вставкой (@PrePersist) автоматически заполняются:
createdBy и createdDate (если поддерживается).
Перед обновлением (@PreUpdate) заполняются:
lastModifiedBy и lastModifiedDate.
Уничтожение
Аудит не влияет на удаление сущностей, но можно добавить @PreRemove логику вручную.
Механизмы Spring и настройки Spring Boot
1. Как работает аудит в Spring Data JPA?
AuditingEntityListener – JPA-колбек, который обрабатывает события @PrePersist и @PreUpdate.
AuditorAware – интерфейс для получения информации о текущем пользователе.
@CreatedDate, @LastModifiedDate, @CreatedBy, @LastModifiedBy – аннотации для полей сущности.
2. Настройка сущности
@Entity
@EntityListeners(AuditingEntityListener.class) // Включение аудита
public class User {
@Id
@GeneratedValue
private Long id;
@CreatedDate
private Instant createdDate;
@LastModifiedDate
private Instant lastModifiedDate;
@CreatedBy
private String createdBy;
@LastModifiedBy
private String lastModifiedBy;
}
3. Конфигурация Spring Boot
Если используется Spring Boot, можно не указывать @EnableJpaAuditing вручную, если:
Есть бин AuditorAware.
Включен spring.data.jpa.repositories.bootstrap-mode=default (по умолчанию).
Пример application.properties:
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
4. Интеграция с Spring Security
Если приложение использует Spring Security, AuditorAware может возвращать текущего пользователя:
@Bean
public AuditorAware<String> auditorAware() {
return () -> Optional.ofNullable(SecurityContextHolder.getContext())
.map(SecurityContext::getAuthentication)
.map(Authentication::getName);
}
Варианты настройки
Отключение аудита для отдельных полей
Не аннотировать поле @CreatedBy, если оно не нужно.
Кастомные даты
Реализовать DateTimeProvider, если требуется использовать не Instant.now(), а другую временную зону.
Аудит без Spring Security
Можно возвращать фиксированное значение (например, "system"):
@Bean
public AuditorAware<String> auditorAware() {
return () -> Optional.of("system");
}
#Java #Training #Hard #Spring #SpringDataJPA #EnableJpaAuditing
Аннотация @EntityListeners
Аннотация @EntityListeners является частью спецификации JPA (Jakarta Persistence API) и позволяет привязать кастомные слушатели (listeners) к сущностям JPA.
Эти слушатели могут перехватывать события жизненного цикла сущности, такие как:
@PrePersist (перед сохранением)
@PostPersist (после сохранения)
@PreUpdate (перед обновлением)
@PostUpdate (после обновлением)
@PreRemove (перед удалением)
@PostRemove (после удалением)
@PostLoad (после загрузкой из БД)
Аннотация находится в пакете jakarta.persistence и применяется на уровне класса сущности.
Параметры аннотации
value (обязательный)
Тип: Массив классов (Class<?>[])
Описание: Принимает один или несколько классов-слушателей, которые должны реализовывать callback-методы JPA.
Пример:
Жизненный цикл слушателей
Регистрация слушателей
При загрузке метаданных JPA провайдер (Hibernate) регистрирует указанные классы-слушатели для сущности.
Вызов callback-методов
При наступлении соответствующего события жизненного цикла JPA вызывает методы слушателей в порядке их объявления.
Порядок выполнения
Если для сущности определено несколько слушателей, их методы выполняются в порядке объявления в аннотации.
Глобальные слушатели (зарегистрированные в orm.xml) выполняются после локальных.
Механизмы работы в Spring
1. Интеграция с Spring
Spring автоматически поддерживает DI в JPA Entity Listeners, если они являются Spring-бинами.
Для этого нужно:
Пометить класс-слушатель как @Component
Зарегистрировать его в Spring-контексте
2. Пример Spring-совместимого слушателя
3. Конфигурация в Spring Boot
Spring Boot автоматически настраивает поддержку Entity Listeners через:
Автоконфигурацию JPA (HibernateJpaAutoConfiguration)
Поддержку инъекции зависимостей в слушатели
Варианты использования
1. Аудит изменений
2. Валидация перед сохранением
3. Кеширование
Ограничения и особенности
Контекст выполнения
Callback-методы выполняются в том же контексте транзакции, что и основная операция.
Исключения
Выброс исключения в callback-методе приводит к откату транзакции.
Порядок выполнения
Методы выполняются в порядке:
Callback-методы самой сущности
Локальные @EntityListeners
Глобальные слушатели
DI ограничения
В чистом JPA слушатели не поддерживают инъекцию зависимостей
В Spring DI работает только для Spring-бинов
#Java #Training #Hard #Spring #SpringDataJPA #EntityListeners
Аннотация @EntityListeners является частью спецификации JPA (Jakarta Persistence API) и позволяет привязать кастомные слушатели (listeners) к сущностям JPA.
Эти слушатели могут перехватывать события жизненного цикла сущности, такие как:
@PrePersist (перед сохранением)
@PostPersist (после сохранения)
@PreUpdate (перед обновлением)
@PostUpdate (после обновлением)
@PreRemove (перед удалением)
@PostRemove (после удалением)
@PostLoad (после загрузкой из БД)
Аннотация находится в пакете jakarta.persistence и применяется на уровне класса сущности.
Параметры аннотации
value (обязательный)
Тип: Массив классов (Class<?>[])
Описание: Принимает один или несколько классов-слушателей, которые должны реализовывать callback-методы JPA.
Пример:
@Entity
@EntityListeners({AuditListener.class, CacheInvalidationListener.class})
public class User {
// поля сущности
}
Жизненный цикл слушателей
Регистрация слушателей
При загрузке метаданных JPA провайдер (Hibernate) регистрирует указанные классы-слушатели для сущности.
Вызов callback-методов
При наступлении соответствующего события жизненного цикла JPA вызывает методы слушателей в порядке их объявления.
Порядок выполнения
Если для сущности определено несколько слушателей, их методы выполняются в порядке объявления в аннотации.
Глобальные слушатели (зарегистрированные в orm.xml) выполняются после локальных.
Механизмы работы в Spring
1. Интеграция с Spring
Spring автоматически поддерживает DI в JPA Entity Listeners, если они являются Spring-бинами.
Для этого нужно:
Пометить класс-слушатель как @Component
Зарегистрировать его в Spring-контексте
2. Пример Spring-совместимого слушателя
@Component
public class AuditListener {
@PrePersist
public void prePersist(Object entity) {
System.out.println("PrePersist: " + entity);
}
@PreUpdate
public void preUpdate(Object entity) {
System.out.println("PreUpdate: " + entity);
}
}
3. Конфигурация в Spring Boot
Spring Boot автоматически настраивает поддержку Entity Listeners через:
Автоконфигурацию JPA (HibernateJpaAutoConfiguration)
Поддержку инъекции зависимостей в слушатели
Варианты использования
1. Аудит изменений
public class AuditListener {
@PrePersist
public void setCreationDate(Object entity) {
if (entity instanceof Auditable) {
((Auditable) entity).setCreatedAt(LocalDateTime.now());
}
}
}
2. Валидация перед сохранением
public class ValidationListener {
@PrePersist
@PreUpdate
public void validate(Object entity) {
if (entity instanceof Validatable) {
((Validatable) entity).validate();
}
}
}
3. Кеширование
public class CacheListener {
@PostPersist
@PostUpdate
@PostRemove
public void invalidateCache(Object entity) {
CacheManager.evict(entity.getClass(), entity.getId());
}
}
Ограничения и особенности
Контекст выполнения
Callback-методы выполняются в том же контексте транзакции, что и основная операция.
Исключения
Выброс исключения в callback-методе приводит к откату транзакции.
Порядок выполнения
Методы выполняются в порядке:
Callback-методы самой сущности
Локальные @EntityListeners
Глобальные слушатели
DI ограничения
В чистом JPA слушатели не поддерживают инъекцию зависимостей
В Spring DI работает только для Spring-бинов
#Java #Training #Hard #Spring #SpringDataJPA #EntityListeners
Аннотация @Projection
Аннотация @Projection используется в Spring Data для определения проекций - специальных интерфейсов или классов, которые позволяют выбирать только определенные поля из сущностей.
Это полезно для:
Оптимизации запросов (избегания select *)
Создания DTO на лету
Кастомизации JSON-представления REST API
Проекции находятся в пакете org.springframework.data.rest.core.config.Projection и применяются к интерфейсам или классам.
Параметры аннотации
types (обязательный)
Тип: Class<?>[]
Описание: Указывает сущности, к которым применяется проекция
Пример:
name (необязательный)
Тип: String
Описание: Задает имя проекции для использования в Spring Data REST
Пример:
Типы проекций
1. Интерфейсные проекции
Наиболее распространенный подход:
2. Классовые проекции (DTO)
Используются классы вместо интерфейсов:
3. Динамические проекции
Можно создавать проекции на лету через SpEL:
Жизненный цикл проекций
Объявление проекции
Создается интерфейс/класс с аннотацией @Projection
Определяются методы, соответствующие полям сущности
Использование в репозитории
Spring Data создает прокси-реализацию при выполнении запроса
Преобразование результатов
После выполнения запроса результаты маппятся на проекцию
Механизмы Spring Data
1. Автоматический маппинг
Spring Data автоматически:
Анализирует методы проекции
Создает соответствующий SQL (только выбранные поля)
Преобразует результат в проекцию
2. Интеграция с репозиториями
3. Поддержка в Spring Data REST
Проекции можно активировать через параметр запроса:
Примеры использования
1. Базовый пример
2. Комплексная проекция
3. Вложенные проекции
Настройки Spring Boot
Автоконфигурация
Spring Boot автоматически настраивает поддержку проекций через SpringDataWebConfiguration
Ручная регистрация
Можно явно зарегистрировать проекции:
Настройка REST
В application.properties:
#Java #Training #Hard #Spring #SpringDataJPA #Projection
Аннотация @Projection используется в Spring Data для определения проекций - специальных интерфейсов или классов, которые позволяют выбирать только определенные поля из сущностей.
Это полезно для:
Оптимизации запросов (избегания select *)
Создания DTO на лету
Кастомизации JSON-представления REST API
Проекции находятся в пакете org.springframework.data.rest.core.config.Projection и применяются к интерфейсам или классам.
Параметры аннотации
types (обязательный)
Тип: Class<?>[]
Описание: Указывает сущности, к которым применяется проекция
Пример:
@Projection(types = {User.class})
public interface UserSummary {
String getUsername();
String getEmail();
}
name (необязательный)
Тип: String
Описание: Задает имя проекции для использования в Spring Data REST
Пример:
@Projection(name = "summary", types = User.class)
public interface UserSummary {...}
Типы проекций
1. Интерфейсные проекции
Наиболее распространенный подход:
@Projection(types = User.class)
public interface UserView {
String getUsername();
String getEmail();
// Можно включать связанные сущности
@Value("#{target.department.name}")
String getDepartmentName();
}
2. Классовые проекции (DTO)
Используются классы вместо интерфейсов:
@Projection(types = User.class)
public class UserDto {
private final String username;
private final String email;
public UserDto(String username, String email) {
this.username = username;
this.email = email;
}
// Геттеры
}
3. Динамические проекции
Можно создавать проекции на лету через SpEL:
@Projection(types = User.class)
public interface DynamicUserView {
@Value("#{target.username + ' (' + target.email + ')'}")
String getDisplayName();
}
Жизненный цикл проекций
Объявление проекции
Создается интерфейс/класс с аннотацией @Projection
Определяются методы, соответствующие полям сущности
Использование в репозитории
Spring Data создает прокси-реализацию при выполнении запроса
Преобразование результатов
После выполнения запроса результаты маппятся на проекцию
Механизмы Spring Data
1. Автоматический маппинг
Spring Data автоматически:
Анализирует методы проекции
Создает соответствующий SQL (только выбранные поля)
Преобразует результат в проекцию
2. Интеграция с репозиториями
public interface UserRepository extends JpaRepository<User, Long> {
<T> List<T> findBy(Class<T> type);
UserSummary findSummaryById(Long id);
}
3. Поддержка в Spring Data REST
Проекции можно активировать через параметр запроса:
GET /users/1?projection=summary
Примеры использования
1. Базовый пример
@Entity
public class User {
private Long id;
private String username;
private String email;
// геттеры/сеттеры
}
@Projection(types = User.class)
public interface UserSummary {
String getUsername();
String getEmail();
}
// В репозитории
UserSummary findSummaryById(Long id);
2. Комплексная проекция
@Projection(types = {User.class, Department.class})
public interface UserDetailView {
String getUsername();
@Value("#{target.department.name}")
String getDepartmentName();
default String getDisplayInfo() {
return getUsername() + " from " + getDepartmentName();
}
}
3. Вложенные проекции
@Projection(types = Order.class)
public interface OrderView {
String getOrderNumber();
@Value("#{target.customer}")
CustomerView getCustomer();
}
@Projection(types = Customer.class)
public interface CustomerView {
String getName();
}
Настройки Spring Boot
Автоконфигурация
Spring Boot автоматически настраивает поддержку проекций через SpringDataWebConfiguration
Ручная регистрация
Можно явно зарегистрировать проекции:
@Configuration
public class ProjectionConfig {
@Bean
public ProjectionDefinitionRegistrar projectionRegistrar() {
return registrar -> {
registrar.addProjection(UserSummary.class);
};
}
}
Настройка REST
В application.properties:
spring.data.rest.default-projection=summary
#Java #Training #Hard #Spring #SpringDataJPA #Projection