Encodera

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

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

Оглавление

Первая сущность

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

Класс Post

Создайте файл src/main/java/com/example/blog/Post.java:

// src/main/java/com/example/blog/Post.java
package com.example.blog;
 
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
 
@Entity
public class Post {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String title;
    private String body;
 
    protected Post() {
    }
 
    public Post(String title, String body) {
        this.title = title;
        this.body = body;
    }
 
    public Long getId() {
        return id;
    }
 
    public String getTitle() {
        return title;
    }
 
    public String getBody() {
        return body;
    }
}
АннотацияЗначение
@EntityКласс хранится в базе
@IdЭто поле — первичный ключ
@GeneratedValueЗначение ключа Hibernate назначает сам

Остальные поля становятся столбцами автоматически. Таблица называется так же, как класс, столбцы — как поля.

Требования к сущности

  • конструктор без параметров — через него Hibernate создаёт объекты при чтении строк. Его можно сделать protected, чтобы ваш код пользовался обычным конструктором;
  • класс и его методы не должны быть final — для ленивой загрузки Hibernate создаёт подклассы;
  • поле с @Id. Удобен тип Long (а не long): null означает «ещё не сохранён».

Запись (record) сущностью быть не может: её поля финальные, а Hibernate нужно их менять.

Регистрация класса

Укажите сущность в единице персистентности в persistence.xml, перед элементом <properties>:

<!-- src/main/resources/META-INF/persistence.xml -->
<persistence-unit name="blog">
  <class>com.example.blog.Post</class>
  <properties>
    <!-- свойства из прошлого урока -->
  </properties>
</persistence-unit>

Сохранение статей

// src/main/java/com/example/blog/Main.java
package com.example.blog;
 
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
 
public class Main {
    public static void main(String[] args) {
        try (EntityManagerFactory emf = Persistence.createEntityManagerFactory("blog")) {
            emf.runInTransaction(em -> {
                Post first = new Post("Привет, Hibernate", "Моя первая статья");
                Post second = new Post("Сущности", "Класс становится таблицей");
                em.persist(first);
                em.persist(second);
                IO.println("Сохранены с id " + first.getId() + " и " + second.getId());
            });
        }
    }
}

runInTransaction открывает транзакцию, передаёт в лямбду EntityManager и в конце фиксирует изменения. persist передаёт объект Hibernate для сохранения. После mvn compile exec:java в консоли:

Hibernate: create sequence Post_SEQ start with 1 increment by 50
Hibernate: create table Post (id bigint not null, body varchar(255), title varchar(255), primary key (id))
Hibernate: select next value for Post_SEQ
Hibernate: select next value for Post_SEQ
Сохранены с id 1 и 2
Hibernate: insert into Post (body,title,id) values (?,?,?)
Hibernate: insert into Post (body,title,id) values (?,?,?)

Hibernate создал таблицу Post и последовательность Post_SEQ для ключей. Обратите внимание на порядок: id известны сразу после persist, а команды insert выполняются только при фиксации транзакции. Почему так — в следующем уроке.

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

Если забыть строку <class>, Hibernate ничего не знает о сущности и падает на первом же persist:

Exception in thread "main" java.lang.IllegalArgumentException: Unknown entity type 'com.example.blog.Post' ('Post' does not belong to this persistence unit)

В обычной Java SE каждую новую сущность нужно добавлять в persistence.xml. Spring Boot и Quarkus находят сущности сами, сканируя пакеты, поэтому там эта строка не нужна.

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

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