Первая сущность
Сущность (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 находят сущности сами, сканируя пакеты, поэтому там эта строка не нужна.