← Назад к вопросам

Что использует Hibernate

2.0 Middle🔥 181 комментариев
#ORM и Hibernate

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI21 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что использует Hibernate

Hibernate — это объектно-реляционный слой (ORM), который использует множество паттернов, технологий и подходов. Расскажу о ключевых компонентах.

Основные технологии и паттерны

1. ORM (Object-Relational Mapping) Отображение объектов Java на таблицы БД:

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "email", unique = true, nullable = false)
    private String email;
    
    @Column(name = "created_at")
    private LocalDateTime createdAt;
    
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private Set<Post> posts;
}

Hibernate автоматически создаёт SQL запросы для операций с БД.

2. Proxy паттерн Для ленивой загрузки (Lazy Loading):

// При загрузке User, посты НЕ загружаются сразу
User user = session.get(User.class, 1L);

// Только при доступе к postsе создаётся SQL запрос
Set<Post> posts = user.getPosts();  // SELECT * FROM posts WHERE user_id = 1

Hibernate создаёт прокси-объект, который загружает данные при обращении.

3. Session (Unit of Work паттерн)

public interface Session {
    Object get(Class<?> clazz, Serializable id);
    void save(Object object);
    void update(Object object);
    void delete(Object object);
    void flush();  // Синхронизация с БД
    void close();
}

4. Identity Map паттерн Hibernate хранит загруженные объекты в кеше (Identity Map), чтобы избежать дублирования:

Session session = sessionFactory.openSession();

User user1 = session.get(User.class, 1L);
User user2 = session.get(User.class, 1L);

// user1 и user2 — один и тот же объект в памяти
assertSame(user1, user2);  // true, потому что Hibernate использует Identity Map

5. Query API и HQL (Hibernate Query Language)

// HQL — объектно-ориентированный язык запросов
Query<User> query = session.createQuery(
    "FROM User WHERE email = :email",
    User.class
);
query.setParameter("email", "john@example.com");
User user = query.getSingleResult();

Hibernate переводит HQL в SQL, оптимизированный для конкретной БД.

Компоненты Hibernate

SessionFactory Фабрика сессий, создаётся один раз при старте приложения:

SessionFactory sessionFactory = new Configuration()
    .addAnnotatedClass(User.class)
    .addAnnotatedClass(Post.class)
    .buildSessionFactory();

Session Основной интерфейс для работы с БД:

Session session = sessionFactory.openSession();
try {
    User user = new User();
    user.setEmail("john@example.com");
    session.save(user);  // INSERT
    session.flush();
} finally {
    session.close();
}

Transaction Управление транзакциями:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
try {
    User user = session.get(User.class, 1L);
    user.setEmail("newemail@example.com");
    session.flush();
    tx.commit();
} catch (Exception e) {
    tx.rollback();
    throw e;
} finally {
    session.close();
}

Кеширование в Hibernate

1. First Level Cache (Session Cache) Автоматический, работает в пределах одной Session:

Session session = sessionFactory.openSession();

User user1 = session.get(User.class, 1L);  // SELECT FROM DB
User user2 = session.get(User.class, 1L);  // Из кеша (нет SQL)

session.close();

2. Second Level Cache (SessionFactory Cache) Опциональный кеш, может быть общим для всех Sessions:

@Entity
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class User {
    // ...
}

Ассоциации и отношения

One-to-Many:

@Entity
public class User {
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private Set<Post> posts;
}

@Entity
public class Post {
    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;
}

Many-to-Many:

@Entity
public class User {
    @ManyToMany
    @JoinTable(
        name = "user_roles",
        joinColumns = @JoinColumn(name = "user_id"),
        inverseJoinColumns = @JoinColumn(name = "role_id")
    )
    private Set<Role> roles;
}

Загрузка данных (Fetch Strategies)

*LAZY (по умолчанию для ToMany):

User user = session.get(User.class, 1L);
// Posts загружаются только при обращении к getPosts()
Set<Post> posts = user.getPosts();  // SELECT * FROM posts WHERE user_id = 1

*EAGER (по умолчанию для ToOne):

Post post = session.get(Post.class, 1L);
// User загружается вместе с Post (LEFT JOIN)
User owner = post.getUser();

Типы запросов

Criteria API:

CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root<User> user = query.from(User.class);

query.select(user)
    .where(cb.equal(user.get("email"), "john@example.com"));

List<User> results = session.createQuery(query).getResultList();

Native SQL:

NativeQuery<User> query = session.createNativeQuery(
    "SELECT * FROM users WHERE email = ?",
    User.class
);
query.setParameter(1, "john@example.com");
User user = query.getSingleResult();

Lifecycle событий (Hibernate Events)

@Entity
@EntityListeners(UserListener.class)
public class User {
    @PrePersist
    void beforeSave() {
        System.out.println("Before insert");
    }
    
    @PostPersist
    void afterSave() {
        System.out.println("After insert");
    }
}

Итого

Hibernate использует:

  • ORM для маппинга объектов на таблицы
  • Proxy паттерн для ленивой загрузки
  • Identity Map паттерн для управления объектами
  • Session (Unit of Work) для управления жизненным циклом
  • Кеширование на двух уровнях
  • HQL для объектно-ориентированных запросов
  • Транзакции для ACID свойств
  • Relationships для моделирования связей между таблицами

Всё вместе это делает Hibernate мощным инструментом для работы с данными в Java приложениях.

Что использует Hibernate | PrepBro