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

Приведи пример использования метода commit() при работе с Hibernate

2.3 Middle🔥 111 комментариев
#ORM и Hibernate

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

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

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

Метод commit() в Hibernate

Метод commit() используется для фиксации (commit) транзакции в БД. Это гарантирует, что все изменения, выполненные в рамках транзакции, постоянно сохраняются в БД.

Основной пример: простой CRUD с commit()

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;

public class UserService {
    private SessionFactory sessionFactory;
    
    // Создание новой записи
    public void createUser(User user) {
        Session session = sessionFactory.openSession();
        Transaction transaction = null;
        
        try {
            transaction = session.beginTransaction();
            session.persist(user); // Добавляем в persistence context
            transaction.commit(); // Фиксируем изменения в БД
            System.out.println("User created successfully");
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback(); // Откатываем при ошибке
            }
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
    
    // Обновление записи
    public void updateUser(Long userId, String newName) {
        Session session = sessionFactory.openSession();
        Transaction transaction = null;
        
        try {
            transaction = session.beginTransaction();
            User user = session.get(User.class, userId);
            if (user != null) {
                user.setName(newName);
                session.merge(user); // Присоединяем detached объект
                transaction.commit(); // Сохраняем изменения
            }
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
    
    // Удаление записи
    public void deleteUser(Long userId) {
        Session session = sessionFactory.openSession();
        Transaction transaction = null;
        
        try {
            transaction = session.beginTransaction();
            User user = session.get(User.class, userId);
            if (user != null) {
                session.remove(user);
                transaction.commit(); // Фиксируем удаление
            }
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
}

Пример с Spring Data JPA (более простой)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserServiceWithSpring {
    @Autowired
    private UserRepository userRepository;
    
    // @Transactional автоматически начинает транзакцию и вызывает commit()
    @Transactional
    public void createUser(User user) {
        userRepository.save(user); // Hibernate автоматически commит'ит
    }
    
    @Transactional
    public void updateUserProfile(Long userId, String name, String email) {
        User user = userRepository.findById(userId).orElseThrow();
        user.setName(name);
        user.setEmail(email);
        userRepository.save(user); // commit() в конце метода
    }
    
    // Несколько операций в одной транзакции
    @Transactional
    public void transferPoints(Long fromUserId, Long toUserId, int points) {
        User from = userRepository.findById(fromUserId).orElseThrow();
        User to = userRepository.findById(toUserId).orElseThrow();
        
        from.setPoints(from.getPoints() - points);
        to.setPoints(to.getPoints() + points);
        
        userRepository.save(from);
        userRepository.save(to);
        // Все изменения коммитятся атомарно
    }
}

Пример с JPA EntityManager

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityTransaction;

@Service
public class OrderService {
    @Autowired
    private EntityManager entityManager;
    
    public void createOrder(Order order) {
        EntityTransaction transaction = entityManager.getTransaction();
        
        try {
            transaction.begin();
            entityManager.persist(order);
            transaction.commit(); // Фиксируем новый заказ
        } catch (Exception e) {
            transaction.rollback();
            throw e;
        }
    }
}

Управление несколькими операциями в одной транзакции

@Service
public class ComplexTransactionService {
    @Autowired
    private SessionFactory sessionFactory;
    
    public void processOrderWithItems(Order order, List<OrderItem> items) {
        Session session = sessionFactory.openSession();
        Transaction transaction = null;
        
        try {
            transaction = session.beginTransaction();
            
            // 1. Сохраняем заказ
            session.persist(order);
            
            // 2. Сохраняем позиции заказа
            for (OrderItem item : items) {
                item.setOrder(order);
                session.persist(item);
            }
            
            // 3. Обновляем количество товара
            for (OrderItem item : items) {
                Product product = session.get(Product.class, item.getProductId());
                product.setStock(product.getStock() - item.getQuantity());
                session.merge(product);
            }
            
            // Все операции выполняются атомарно
            transaction.commit();
            System.out.println("Order processed successfully");
            
        } catch (Exception e) {
            // Если ошибка - откатываем всё
            if (transaction != null && transaction.isActive()) {
                transaction.rollback();
            }
            System.out.println("Order processing failed, all changes rolled back");
            throw e;
        } finally {
            session.close();
        }
    }
}

Жизненный цикл объекта и commit()

// Состояния объекта при commit()
public class EntityLifecycle {
    public void demonstrateLifecycle() {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        
        // 1. TRANSIENT: не присоединен к сессии
        User user = new User();
        user.setName("John");
        
        // 2. PERSISTENT: присоединен к сессии
        session.persist(user); // user теперь в persistence context
        
        // 3. Изменения отслеживаются
        user.setName("Jane");
        
        // 4. commit() отправляет UPDATE в БД
        transaction.commit(); // SQL: UPDATE users SET name='Jane' WHERE id=...
        
        // 5. DETACHED: объект больше не присоединен
        session.close();
        // user теперь detached, но в памяти
        
        // 6. Изменения после close не отслеживаются
        user.setName("Alice"); // Это не будет сохранено в БД!
    }
}

Различные сценарии commit()

// Сценарий 1: Автоматический commit при autoCommit=true
public void autoCommitExample() {
    Session session = sessionFactory.openSession();
    // autoCommit по умолчанию false в Hibernate
    
    User user = new User();
    user.setName("Test");
    session.persist(user);
    // Без явного commit() изменения НЕ будут сохранены!
    session.close();
}

// Сценарий 2: Частичный commit (savepoint)
public void savepointExample() {
    Session session = sessionFactory.openSession();
    Transaction transaction = session.beginTransaction();
    
    User user1 = new User();
    user1.setName("User1");
    session.persist(user1);
    
    // Создаем savepoint
    transaction.commit();
    Transaction transaction2 = session.beginTransaction();
    
    User user2 = new User();
    user2.setName("User2");
    session.persist(user2);
    transaction2.commit();
    
    session.close();
}

// Сценарий 3: Откат при ошибке
public void rollbackExample() {
    Session session = sessionFactory.openSession();
    Transaction transaction = session.beginTransaction();
    
    try {
        User user = new User();
        user.setName("Valid");
        session.persist(user);
        
        // Имитируем ошибку
        if (someErrorCondition()) {
            throw new BusinessException("Invalid operation");
        }
        
        transaction.commit(); // Выполняется только если нет ошибки
    } catch (Exception e) {
        transaction.rollback(); // Откатываем ВСЕ изменения
        System.out.println("Transaction rolled back");
    } finally {
        session.close();
    }
}

Best Practices

  1. Используй @Transactional в Spring:
@Transactional // Автоматический commit/rollback
public void complexOperation() {
    // код
}
  1. Всегда откатывай при ошибке:
try {
    transaction.commit();
} catch (Exception e) {
    if (transaction != null && transaction.isActive()) {
        transaction.rollback();
    }
}
  1. Закрывай Session в finally:
finally {
    if (session != null) {
        session.close();
    }
}
  1. Группируй связанные операции:
transaction.begin();
// ВСЕ связанные операции
transaction.commit();
// Либо все сохраняются, либо все откатываются

Metod commit() — ключевой механизм обеспечения целостности данных в Hibernate и гарантирует ACID свойства транзакций.

Приведи пример использования метода commit() при работе с Hibernate | PrepBro