@Transactional noRollbackFor example using spring boot

In this post we are going to see about @Transactional(noRollbackFor = { SomeException.class }) example using Spring Boot. We will also see what is the effect of using noRollbackFor, how to use noRollBackFor attribute in the real-time scenario. Let’s see some points related to the noRollbackFor attribute.

Understanding Spring @Transactional(noRollbackFor = { SomeException.class })

As the name suggests (noRollBackFor), if we don’t want our transaction to be get rollbacked for any specific RuntimeException, we can use @Transactional noRollBackFor attribute.

Generally, if we are using @Transactional annotation with the method and some RuntimeException(for eg – NullPointerException, ClassCastException) comes, the transaction will get rollbacked(See @Transactional rollBackFor example for more details). This is the default behavior, if we don’t use noRollBackFor attribute.

Suppose some exception is good, we like that exception and we don’t want our transaction to get rollbacked even that exception occurs. For example, for any specific transaction, if NullPointerException comes, we don’t want to our transaction to be get rollbacked then we can use notRollBackFor as below.

We can use noRollbackFor attribute as a parameter with @Transnational annotation as follows.

@Transactional(noRollbackFor = { RuntimeException.class })
public void saveBook(Book book) {
	// some logic
}

Let’s see an example where we will use noRollbackFor = {NullPoniterException.class}

@Transactional(noRollbackFor = {NullPoniterException.class})
public void saveBook(Book book) {
	// some logic
}

Spring @Transactional noRollbackFor example using spring boot and Oracle.

Prerequisites.

  • JDK 1.8
  • Oracle 10g
  • Eclipse
  • maven
  • postman

Step 1 – open eclipse and create maven project, Don’t forget to check ‘Create a simple project (skip) and click on next.

Step 2 – Fill all details as below and click on finish.

Step 3 – Replace the pom.xml with below code.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>springtransactionexample</groupId>
  <artifactId>springtransactionexample</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>springtransactionexample</name>
  
  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>
 </parent>
  <dependencies>
	<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
      
   </dependencies>
   
   
    
   
</project>

Step 4 – Create the below directory structure.

Step 5 – Define the following classes and interfaces.

Book.java

package com.springtransaction.entity;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "book")
public class Book {
	 
	 @Id
	 @GeneratedValue(strategy = GenerationType.AUTO)
	 private int bookId;
	 
	 @Column(name="book_name")
	 private String bookName;
	 
	 @Column(name="auther_name")
	 private String autherName;
	 
	 @Column(name="price")
	 private int price;	 
	
	public String getAutherName() {
		return autherName;
	}

	public void setAutherName(String autherName) {
		this.autherName = autherName;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}
	
	public String getBookName() {
		return bookName;
	}

	public void setBookName(String bookName) {
		this.bookName = bookName;
	}

	public int getBookId() {
		return bookId;
	}

	public void setBookId(int bookId) {
		this.bookId = bookId;
	}		 	 
}

BookService.java – interface

package com.springtransaction.service;

import java.util.List;

import org.springframework.stereotype.Component;

import com.springtransaction.entity.Book;

@Component
public interface BookService {
	public void saveBook(Book book);

}

BookRepository.java – interface

package com.springtransaction.repository;

import java.io.Serializable;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.springtransaction.entity.Book;

@Repository
public interface BookRepository extends CrudRepository<Book,Serializable> {
		
}

BookServiceImpl.java

package com.springtransaction.serviceimpl;

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

import com.springtransaction.entity.Book;
import com.springtransaction.repository.BookRepository;
import com.springtransaction.service.BookService;

@Service
public class BookServiceImpl implements BookService {

	@Autowired
	private BookRepository bookRepository;

	@Transactional(noRollbackFor = {NullPointerException.class})
	public void saveBook(Book book) {
		Book book1 = null;
		// save book
		book1 = bookRepository.save(book);
                String s1 = null;
                System.out.println(s1.hashCode())
	}
}

BookController.java

package com.springtransaction.controller;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.springtransaction.entity.Book;
import com.springtransaction.service.BookService;

@RestController
@RequestMapping("/book")
public class BookController {
	@Autowired
	private BookService bookService;
	
	@RequestMapping(value = "/savebook",method = RequestMethod.POST)
        @ResponseBody
        public Book saveBook(@RequestBody Book book) {
		bookService.saveBook(book);
		return book;
	}		
}

JpaConfig.java

package com.springtransaction.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@Configuration
@EnableJpaRepositories(basePackages = "com.springtransaction.repository")
public class JpaConfig {

}

SpringMainExample.java

package com.springtransaction.springtransaction;

import org.hibernate.SessionFactory;
import org.hibernate.jpa.HibernateEntityManagerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;

import com.springtransaction.entity.Book;
import com.springtransaction.service.BookService;

@SpringBootApplication(scanBasePackages={"com.springtransaction"})
@EntityScan("com.springtransaction.*") 
public class SpringMainExample {
			
	public static void main(final String[] args) {
		final ConfigurableApplicationContext configurableApplicationContext = SpringApplication
				.run(SpringMainExample.class, args);				
	}							
}

And finally, we have application.properties

spring.datasource.url=jdbc:oracle:thin:@localhost:1521:XE
spring.datasource.username=SYSTEM
spring.datasource.password=oracle1
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
 
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
 
spring.jpa.show-sql = true
 
spring.jpa.hibernate.ddl-auto =create
 
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.Oracle10gDialect
 
server.port = 9091
 

We are good now. Let’s run the application.

Test from postman with below request data.

Let’s check the DB.

Even we have NullPointerException in our code, we have one record in the database. If you remove noRollbackFor = {NullPointerException.class} from @Transactional annotation, it will not save any record.

Real time scenario when to use @Transactinal noRollbackFor = {SomeException.class}.

We may have business requirement while login we want to store username and password, it doesn’t matter user is authorised or not. Suppose we have some custom exception according to our requirement i.e UserUnUthorizedException. Whenever some user login with the wrong username or password exception should come. Even user is not authenticated successfully, we may want to save the record in DB to know what credentials user is using. In this scenario, we can use noRollbackFor ={UserUnUthorizedException.class} attribute with @Transactional annotation.

The same way we can use for another different scenario where even exception comes we don’t want to get transaction rollbacked.

That’s all about @Transactional noRollbackFor example using spring boot.

You may like.

Spring @Transactional noRollBackFor docs.

Summary – We have seen how to use @Transactional noRollbackFor attribue.