Столбцы и типы
По умолчанию Hibernate делает столбец из каждого поля: с именем поля, подходящим типом и varchar(255) для строк. Для начала этого хватает, но настоящей таблице нужно больше: обязательные столбцы, длина строк, свои имена. Всё это задаётся аннотациями на полях.
Post посложнее
// src/main/java/com/example/blog/PostStatus.java
package com.example.blog;
public enum PostStatus {
DRAFT, PUBLISHED, ARCHIVED
}// src/main/java/com/example/blog/Post.java
package com.example.blog;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import java.time.LocalDateTime;
@Entity
@Table(name = "posts")
public class Post {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false, length = 200)
private String title;
@Column(length = 10_000)
private String body;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private PostStatus status = PostStatus.DRAFT;
@Column(name = "published_at")
private LocalDateTime publishedAt;
private int views;
@Transient
private boolean selected;
protected Post() {
}
public Post(String title, String body) {
this.title = title;
this.body = body;
}
public void publish() {
status = PostStatus.PUBLISHED;
publishedAt = LocalDateTime.of(2026, 3, 15, 10, 0);
}
// геттеры
}Hibernate создаёт такую таблицу:
Hibernate: create table posts (views integer not null, id bigint not null, published_at timestamp(6), title varchar(200) not null, body varchar(10000), status enum ('ARCHIVED','DRAFT','PUBLISHED') not null, primary key (id))| Аннотация | Что делает |
|---|---|
@Table(name = "posts") | Имя таблицы вместо имени класса |
@Column(name = "published_at") | Имя столбца вместо имени поля |
nullable = false | Добавляет not null |
length = 200 | Длина строки: varchar(200) |
@Enumerated(EnumType.STRING) | Хранить константу перечисления по имени |
@Transient | Не хранить поле вовсе |
В H2 и MySQL есть особый тип столбца enum; в PostgreSQL то же отображение даёт столбец varchar с проверкой допустимых значений.
Типы Java и SQL
| Java | SQL (H2) |
|---|---|
String | varchar(255) |
int, long | integer not null, bigint not null |
boolean | boolean not null |
BigDecimal | numeric(38,2) |
LocalDate | date |
LocalDateTime | timestamp(6) |
Instant | timestamp(6) with time zone |
Примитивные типы всегда получают not null: примитив не может хранить null. Для денег используйте BigDecimal, а не double. Для длинных текстов есть ещё @Lob — он даёт столбец clob.
Проверяем, что сохранилось
// src/main/java/com/example/blog/Main.java
emf.runInTransaction(em -> {
Post post = new Post("Отображение столбцов", "Типы, перечисления и даты");
post.publish();
em.persist(post);
});
Object[] row = emf.callInTransaction(em -> (Object[]) em
.createNativeQuery("select title, status, published_at, views from posts")
.getSingleResult());
IO.println(java.util.Arrays.toString(row));Программа читает строку обычным SQL и печатает её:
[Отображение столбцов, PUBLISHED, 2026-03-15T10:00, 0]Статус хранится текстом PUBLISHED, дата — как отметка времени.
Частая ошибка
Без @Enumerated(EnumType.STRING) перечисление хранится номером позиции:
Hibernate: create table posts (status tinyint not null check ((status between 0 and 2)), ...)DRAFT превращается в 0, PUBLISHED — в 1. Если позже кто-то добавит константу в начало перечисления, все старые строки незаметно поменяют смысл. Всегда пишите @Enumerated(EnumType.STRING).