Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Столбцы и типы

По умолчанию 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

JavaSQL (H2)
Stringvarchar(255)
int, longinteger not null, bigint not null
booleanboolean not null
BigDecimalnumeric(38,2)
LocalDatedate
LocalDateTimetimestamp(6)
Instanttimestamp(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).

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.