Encodera

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

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

Оглавление

Сущности

Сущность (entity) — это класс Java, объекты которого хранятся в таблице базы данных. Одна строка таблицы — один объект, один столбец — одно поле. Связь между классом и таблицей задают аннотации JPA, а Hibernate по ним сам строит SQL.

Сущность статьи

Запись Post из прошлой главы заменим классом. Удалите старый Post.java и создайте новый:

// src/main/java/com/example/blog/Post.java
package com.example.blog;
 
import java.time.Instant;
 
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
 
@Entity
@Table(name = "posts")
public class Post {
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
 
    @Column(nullable = false, length = 120)
    private String title;
 
    @Column(nullable = false, length = 10000)
    private String body;
 
    @Column(nullable = false)
    private String author;
 
    @Column(nullable = false)
    private Instant createdAt;
 
    protected Post() {
    }
 
    public Post(String title, String body, String author, Instant createdAt) {
        this.title = title;
        this.body = body;
        this.author = author;
        this.createdAt = createdAt;
    }
 
    public Long getId() {
        return id;
    }
 
    public String getTitle() {
        return title;
    }
 
    public void setTitle(String title) {
        this.title = title;
    }
 
    public String getBody() {
        return body;
    }
 
    public void setBody(String body) {
        this.body = body;
    }
 
    public String getAuthor() {
        return author;
    }
 
    public Instant getCreatedAt() {
        return createdAt;
    }
}

Что значат аннотации

АннотацияСмысл
@EntityКласс хранится в базе
@Table(name = "posts")Имя таблицы; без неё было бы post
@IdПервичный ключ
@GeneratedValue(strategy = IDENTITY)Номер назначает база при вставке строки
@Column(nullable = false, length = 120)Столбец NOT NULL, длина до 120 символов

Поля без аннотаций тоже становятся столбцами. Имена Hibernate переводит в стиль SQL: поле createdAt превращается в столбец created_at.

Почему не запись

Hibernate создаёт объект пустым, а потом заполняет поля из строки таблицы. Для этого ему нужен конструктор без параметров, а для изменения — изменяемые поля. У записей нет ни того, ни другого, поэтому сущности — обычные классы. Конструктор без параметров объявлен protected: он нужен Hibernate, а в своём коде мы пользуемся вторым конструктором.

Сеттеры есть только у заголовка и текста — автор и дата создания после публикации не меняются.

Что получилось в базе

При запуске с ddl-auto: update Hibernate сам создаст таблицу и напечатает SQL:

Hibernate: create table posts (id bigint generated by default as identity, author varchar(255) not null, body varchar(10000) not null, created_at timestamp(6) with time zone not null, title varchar(120) not null, primary key (id))

Instant стал timestamp with time zone, Long — bigint, а длина author по умолчанию — 255 символов. Таблицу можно увидеть в консоли /h2-console. Самого хранилища статей пока нет — его заменит репозиторий из следующего урока.

Частая ошибка

Если забыть @Id, приложение не запустится:

Entity 'com.example.blog.Post' has no identifier (every '@Entity' class must declare or inherit at least one '@Id' or '@EmbeddedId' property)

У каждой сущности должен быть первичный ключ. Проверьте и импорт: аннотации берутся из пакета jakarta.persistence. Старый пакет javax.persistence из примеров для Spring Boot 2 в современных версиях не работает.

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

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