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 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
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
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.