or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

exception-translation.mdhibernate-configuration.mdhibernate-transaction-management.mdindex.mdjpa-configuration.mdjpa-transaction-management.mdjpa-vendor-adapters.mdpersistence-unit-management.mdshared-resources.mdutility-classes.mdweb-integration.md
tile.json

hibernate-transaction-management.mddocs/

Hibernate Native Transaction Management

Transaction management for native Hibernate Session instances with Spring's declarative transaction infrastructure.

Quick Setup

import org.hibernate.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
public class HibernateConfig {

    @Bean
    public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
        return new HibernateTransactionManager(sessionFactory);
    }
}

Service Layer Usage

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.List;

@Service
@Transactional
public class ProductService {

    private final SessionFactory sessionFactory;

    public ProductService(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public Product create(String name, BigDecimal price) {
        Session session = sessionFactory.getCurrentSession();
        Product product = new Product();
        product.setName(name);
        product.setPrice(price);
        session.persist(product);
        return product;
    }

    @Transactional(readOnly = true)
    public Product findById(Long id) {
        Session session = sessionFactory.getCurrentSession();
        return session.get(Product.class, id);
    }

    public void update(Long id, String name) {
        Session session = sessionFactory.getCurrentSession();
        Product product = session.get(Product.class, id);
        if (product != null) {
            product.setName(name);
            // Flush happens automatically on transaction commit
        }
    }

    public void delete(Long id) {
        Session session = sessionFactory.getCurrentSession();
        Product product = session.load(Product.class, id);
        session.remove(product);
    }

    @Transactional(readOnly = true)
    public List<Product> search(String namePattern) {
        Session session = sessionFactory.getCurrentSession();
        return session.createQuery(
            "from Product p where p.name like :pattern", Product.class)
            .setParameter("pattern", "%" + namePattern + "%")
            .list();
    }
}

Configuration with Connection Preparation

import javax.sql.DataSource;

@Bean
public HibernateTransactionManager transactionManager(
        SessionFactory sessionFactory, DataSource dataSource) {
    HibernateTransactionManager txManager = new HibernateTransactionManager();
    txManager.setSessionFactory(sessionFactory);
    txManager.setDataSource(dataSource);
    txManager.setPrepareConnection(true);  // Enable for read-only txns
    return txManager;
}

Advanced Transaction Configuration

import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;

@Service
public class OrderService {

    private final SessionFactory sessionFactory;

    public OrderService(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Transactional(
        isolation = Isolation.SERIALIZABLE,
        propagation = Propagation.REQUIRED,
        timeout = 30,
        rollbackFor = {BusinessException.class}
    )
    public Order processOrder(OrderRequest request) {
        Session session = sessionFactory.getCurrentSession();
        Order order = new Order();
        // Process order
        session.persist(order);
        return order;
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void logOrderEvent(Long orderId, String eventType) {
        // Always executed in new transaction
        Session session = sessionFactory.getCurrentSession();
        OrderEvent event = new OrderEvent();
        event.setOrderId(orderId);
        event.setEventType(eventType);
        session.persist(event);
    }

    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public OrderStatistics calculateStatistics() {
        // Executed outside transaction context
        Session session = sessionFactory.getCurrentSession();
        // Calculate statistics
        return new OrderStatistics();
    }
}

Programmatic Transaction Management

import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.transaction.PlatformTransactionManager;

@Service
public class ProductService {

    private final TransactionTemplate transactionTemplate;
    private final SessionFactory sessionFactory;

    public ProductService(HibernateTransactionManager transactionManager,
                         SessionFactory sessionFactory) {
        this.transactionTemplate = new TransactionTemplate(transactionManager);
        this.sessionFactory = sessionFactory;
    }

    public Product createProgrammatically(String name, BigDecimal price) {
        return transactionTemplate.execute(status -> {
            Session session = sessionFactory.getCurrentSession();
            Product product = new Product();
            product.setName(name);
            product.setPrice(price);
            session.persist(product);
            return product;
        });
    }

    public void updateWithRollback(Long id, String name) {
        transactionTemplate.execute(status -> {
            try {
                Session session = sessionFactory.getCurrentSession();
                Product product = session.get(Product.class, id);
                product.setName(name);

                if (name.contains("invalid")) {
                    status.setRollbackOnly();  // Manually mark for rollback
                }
            } catch (Exception e) {
                status.setRollbackOnly();
                throw e;
            }
            return null;
        });
    }
}

Session Management

Generic DAO Pattern

@Repository
public class GenericDao<T> {

    private final SessionFactory sessionFactory;
    private final Class<T> entityClass;

    public GenericDao(SessionFactory sessionFactory, Class<T> entityClass) {
        this.sessionFactory = sessionFactory;
        this.entityClass = entityClass;
    }

    protected Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

    public T findById(Long id) {
        return getCurrentSession().get(entityClass, id);
    }

    public void save(T entity) {
        getCurrentSession().persist(entity);
    }

    public void update(T entity) {
        getCurrentSession().merge(entity);
    }

    public void delete(T entity) {
        getCurrentSession().remove(entity);
    }

    public List<T> findAll() {
        CriteriaBuilder cb = getCurrentSession().getCriteriaBuilder();
        CriteriaQuery<T> cq = cb.createQuery(entityClass);
        cq.from(entityClass);
        return getCurrentSession().createQuery(cq).getResultList();
    }
}

Batch Processing

@Service
@Transactional
public class BatchService {

    private final SessionFactory sessionFactory;

    public BatchService(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public void processBatch(List<Product> products) {
        Session session = sessionFactory.getCurrentSession();
        int batchSize = 50;

        for (int i = 0; i < products.size(); i++) {
            session.persist(products.get(i));

            if (i > 0 && i % batchSize == 0) {
                session.flush();  // Write to database
                session.clear();  // Clear persistence context
            }
        }
    }
}

API Reference

class HibernateTransactionManager {

    // Constructors
    HibernateTransactionManager();
    HibernateTransactionManager(SessionFactory sessionFactory);

    // SessionFactory configuration
    void setSessionFactory(SessionFactory sessionFactory);
    SessionFactory getSessionFactory();

    // DataSource (for exception translation)
    void setDataSource(DataSource dataSource);
    DataSource getDataSource();
    void setAutodetectDataSource(boolean autodetect);

    // Connection preparation
    void setPrepareConnection(boolean prepareConnection);

    // Hibernate properties
    void setHibernateProperties(Properties properties);

    // Entity interceptor
    void setEntityInterceptor(Interceptor interceptor);
    void setEntityInterceptorBeanName(String beanName);

    // JDBC exception translator
    void setJdbcExceptionTranslator(SQLExceptionTranslator translator);
}

Related Topics

  • Hibernate Configuration - SessionFactory setup
  • JPA Transaction Management - JPA alternative