Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
FAQs Support
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

Hibernate Spring Integration

Spring + Hibernate Integration

Spring integrates seamlessly with Hibernate. The most common approach is to use Spring Data JPA with Hibernate as the JPA provider. Spring manages the SessionFactory/EntityManagerFactory, transactions, and exception translation automatically.

Spring Boot + Hibernate Configuration
# Spring Boot auto-configures Hibernate as JPA provider
spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=false
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# JPA/Hibernate settings
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect

# Connection pool (HikariCP - Spring Boot default)
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.connection-timeout=30000

# Hibernate statistics (for debugging)
spring.jpa.properties.hibernate.generate_statistics=false
<dependencies>
    <!-- Spring Boot Starter Data JPA (includes Hibernate) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <!-- MySQL Driver -->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

@Transactional with Spring

@Transactional Service Layer
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional // All methods are transactional by default
public class OrderService {

    private final OrderRepository orderRepository;
    private final UserRepository userRepository;
    private final ProductRepository productRepository;

    public OrderService(OrderRepository orderRepository,
                        UserRepository userRepository,
                        ProductRepository productRepository) {
        this.orderRepository = orderRepository;
        this.userRepository  = userRepository;
        this.productRepository = productRepository;
    }

    // Read-only transaction (optimization)
    @Transactional(readOnly = true)
    public List<Order> getUserOrders(Long userId) {
        return orderRepository.findByUserId(userId);
    }

    // Write transaction - rolls back on any RuntimeException
    @Transactional
    public Order placeOrder(Long userId, Long productId, int quantity) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("User not found"));

        Product product = productRepository.findById(productId)
                .orElseThrow(() -> new RuntimeException("Product not found"));

        if (product.getStock() < quantity) {
            throw new RuntimeException("Insufficient stock"); // Triggers rollback
        }

        // Deduct stock
        product.setStock(product.getStock() - quantity);
        productRepository.save(product);

        // Create order
        Order order = new Order();
        order.setUser(user);
        order.setProduct(product);
        order.setQuantity(quantity);
        order.setTotal(product.getPrice() * quantity);

        return orderRepository.save(order);
        // Transaction commits here if no exception
    }

    // Rollback only on specific exceptions
    @Transactional(rollbackFor = {Exception.class},
                   noRollbackFor = {IllegalArgumentException.class})
    public void processPayment(Long orderId) throws Exception {
        // ...
    }
}

Using EntityManager Directly

EntityManager in Spring
import jakarta.persistence.*;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
@Transactional
public class CustomUserRepository {

    // Spring injects EntityManager (thread-safe proxy)
    @PersistenceContext
    private EntityManager em;

    public User findById(Long id) {
        return em.find(User.class, id);
    }

    public List<User> findByRole(String role) {
        return em.createQuery("FROM User u WHERE u.role = :role", User.class)
                .setParameter("role", role)
                .getResultList();
    }

    public User save(User user) {
        if (user.getId() == null) {
            em.persist(user);
            return user;
        } else {
            return em.merge(user);
        }
    }

    public void delete(Long id) {
        User user = em.find(User.class, id);
        if (user != null) em.remove(user);
    }

    // Access Hibernate Session from EntityManager
    public void hibernateSpecificOperation(Long id) {
        org.hibernate.Session session = em.unwrap(org.hibernate.Session.class);
        User user = session.get(User.class, id);
        // Use Hibernate-specific features
    }
}

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.