junior
Основные аннотации маппинга сущностей
Аннотации JPA определяют, как Java-классы и поля маппятся на таблицы и столбцы.
Пример полного маппинга сущности
@Entity // класс — JPA-сущность
@Table(name = "users", // таблица в БД
uniqueConstraints = @UniqueConstraint(columnNames = "email"),
indexes = @Index(columnList = "name"))
public class User {
@Id // первичный ключ
@GeneratedValue(strategy = GenerationType.IDENTITY) // автоинкремент
private Long id;
@Column(name = "user_name", // имя столбца
nullable = false, // NOT NULL
length = 100) // VARCHAR(100)
private String name;
@Column(unique = true, nullable = false)
private String email;
@Enumerated(EnumType.STRING) // enum как строка (не ordinal!)
@Column(nullable = false)
private UserStatus status;
@Temporal(TemporalType.TIMESTAMP) // для java.util.Date (не нужен для LocalDateTime)
private Date createdAt;
@Lob // BLOB/CLOB — для больших объектов
private String description;
@Transient // не маппится в БД
private String temporaryField;
@Embedded // встраиваемый объект
private Address address;
@Version // оптимистичная блокировка
private Long version;
}
@Embeddable // встраиваемый компонент (без своей таблицы)
public class Address {
private String city;
private String street;
@Column(name = "zip_code")
private String zipCode;
}
Краткая таблица аннотаций
| Аннотация | Назначение |
|---|---|
@Entity |
Маркирует класс как JPA-сущность |
@Table |
Настройка таблицы (имя, уникальные ограничения, индексы) |
@Id |
Первичный ключ |
@GeneratedValue |
Стратегия генерации ID |
@Column |
Настройка столбца (имя, nullable, unique, length) |
@Enumerated |
Маппинг enum (STRING или ORDINAL) |
@Temporal |
Тип для java.util.Date |
@Lob |
Большие объекты (BLOB, CLOB) |
@Transient |
Поле не маппится в БД |
@Embedded / @Embeddable |
Встраиваемый объект без собственной таблицы |
@Version |
Поле для оптимистичной блокировки |
Важное
@Entityобязательна; класс должен иметь конструктор без аргументов и@Id@Columnнеобязательна — без неё поле маппится по имени@Enumerated(EnumType.STRING)— всегда используйте STRING, не ORDINAL (добавление значения в enum сломает данные)@Embedded/@Embeddable— способ декомпозиции сущности без создания отдельной таблицы
Частые ошибки
@Enumerated(EnumType.ORDINAL)— при изменении порядка элементов enum данные в БД станут некорректными- Отсутствие
@Version— без оптимистичной блокировки потерянные обновления (lost updates) неизбежны при конкурентном доступе @Column(nullable = false)без NOT NULL в БД — аннотация влияет только на DDL-генерацию; если БД уже создана через миграции, ограничение нужно добавлять в миграции- Маппинг
boolean→@Column— по умолчанию маппится в BIT/BOOLEAN, но в Oracle нет BOOLEAN; нужен@Column(columnDefinition = "NUMBER(1)")
Как используется в 2026
- Hibernate 6.x поддерживает Java Records как
@Embeddable— удобнее для Value Objects @JdbcTypeCode(SqlTypes.JSON)— нативная поддержка JSON-столбцов в Hibernate 6- Temporal API (LocalDate, LocalDateTime) маппится без
@Temporalначиная с JPA 2.2 @SoftDelete(Hibernate 6.4) — встроенная поддержка мягкого удаления
На собеседовании: минимальный набор, который нужно знать:
@Entity,@Table,@Id,@GeneratedValue,@Column,@Enumerated(STRING). Интервьюер часто спрашивает про ORDINAL vs STRING — правильный ответ всегда STRING. Бонус — упомянуть@Versionдля оптимистичной блокировки и@Embeddableдля Value Objects.