Thursday, May 21, 2020

Spring Transaction Management Example - @Transactional Annotation and JDBC

In the post Transaction Management in Spring we have already seen the details about transaction management in Spring. In this post, building on that knowledge we’ll see an example of transaction management in Spring with JDBC. This Spring transaction management example uses declarative transaction using @Transactional annotation.

Technologies used

  • Spring 5.0.4
  • Apache DBCP2
  • MYSQL 5.1.39
  • Java 8
  • Apache Maven 3.3.3

In the transaction management example, Apache DBCP is used for providing pooled JDBC datasource and MYSQL is used as the back end.


Maven dependencies

If you are using Maven then you can provide dependencies in your pom.xml.

Refer Creating a Maven Project in Eclipse to see how to set up Maven project.

With all the required dependencies your pom.xml should look something like this -

<?xml version="1.0" encoding="UTF-8"?>

<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>org.netjs.spring</groupId>
  <artifactId>SpringProj</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  
  <name>SpringProj</name>
  <url>http://maven.apache.org</url>

  <properties>
    <java.version>1.8</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring.version>5.0.4.RELEASE</spring.version>
  </properties>

  <dependencies>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    
     <dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
    </dependency>
    
    <!-- Spring JDBC Support -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    
   <!-- MySQL Driver -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.39</version>
    </dependency>
    
    <!--  Apache DBCP connection pool -->
    <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-dbcp2</artifactId>
       <version>2.1</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Alternatively you can download the jars and add them to the class path.

Spring declarative transaction management JDBC example

Now the basic project structure is in place and we should create DB tables and classes for the project. In this Spring transaction management example we’ll have two DB tables employee and address and when employee record and employee’s address records are inserted with in a transaction, either both of them should be inserted correctly or none of them.

Database tables

Here is the table structure for both employee and address tables.

CREATE TABLE `employee` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(35) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) 
CREATE TABLE `address` (
  `id` int(11) NOT NULL,
  `address` varchar(20) DEFAULT NULL,
  `city` varchar(20) DEFAULT NULL,
  KEY `id_idx` (`id`),
  CONSTRAINT `id` FOREIGN KEY (`id`) REFERENCES `employee` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
)

JDBC Data Source

For this example Apache DBCP is used and DB properties are read from a properties file.

Bean definition for data source is as follows-
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
    <property name="driverClassName" value = "${db.driverClassName}" />
    <property name="url" value = "${db.url}" />
    <property name="username" value = "${db.username}" />
    <property name="password" value = "${db.password}" />
    <property name="initialSize" value = "${pool.initialSize}" />
</bean>

db.properties file

db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/netjs
db.username=
db.password=
pool.initialSize=5

Spring transaction management example – Java classes

The flow in the example is; first service bean is called which in turn calls a DAO class and from there the DB call.

The classes needed for this flow are as follows-

  1. Employee and Address Beans
  2. Service interface and Service implementation class
  3. DAO interface and DAO implementation class.
With all these classes project structure will look like as follows-
spring transaction management example

Employee.java

public class Employee {
 private int empId;
 private String empName;
 private int age;
 private Address address;
 public int getEmpId() {
  return empId;
 }
 public void setEmpId(int empId) {
  this.empId = empId;
 }
 public String getEmpName() {
  return empName;
 }
 public void setEmpName(String empName) {
  this.empName = empName;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 public Address getAddress() {
  return address;
 }
 public void setAddress(Address address) {
  this.address = address;
 }
}

Address.java

public class Address {
 private int id;
 private String addrLine; 
 private String city;
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getAddrLine() {
  return addrLine;
 }
 public void setAddrLine(String addrLine) {
  this.addrLine = addrLine;
 }
 public String getCity() {
  return city;
 }
 public void setCity(String city) {
  this.city = city;
 } 
}

EmployeeDAO.java interface

public interface EmployeeDAO {
  public Employee findEmployee(int empId);
  public void insertEmployee(Employee emp);
}

EmployeeDAOImpl.java

@Repository
public class EmployeeDAOImpl implements EmployeeDAO {
  @Autowired
  private JdbcTemplate jdbcTemplate; 
  @Override
  public Employee findEmployee(int empId) {
    final String SELECT_BY_ID_QUERY = "select emp.id, name, age, address, city from employee emp, address adr "
        + "where emp.id = adr.id and emp.id = ?";
    return this.jdbcTemplate.queryForObject(SELECT_BY_ID_QUERY, 
          new EmployeeMapper(), 
          empId);
  }
    
  private static final class EmployeeMapper implements RowMapper<Employee> {
    public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
      Employee emp = new Employee();
      Address addr = new Address();
      emp.setEmpId(rs.getInt("id"));
      emp.setEmpName(rs.getString("name"));
      emp.setAge(rs.getInt("age"));
      addr.setAddrLine("address");
      addr.setCity("city");
      emp.setAddress(addr);
      return emp;
    }
  }
    
  @Override
  public void insertEmployee(Employee emp) {
    final String INSERT_EMP_QUERY = "insert into employee (id, name, age) values (?, ?, ?)";
    final String INSERT_ADDR_QUERY = "insert into address (id, address, city) values (?, ?, ?)";

    jdbcTemplate.update(INSERT_EMP_QUERY, emp.getEmpId(), emp.getEmpName(), emp.getAge());
    System.out.println("Employee record inserted");
    jdbcTemplate.update(INSERT_ADDR_QUERY, emp.getEmpId(), emp.getAddress().getAddrLine(), emp.getAddress().getCity());
    System.out.println("Employee address record inserted");
  }
}

In the EmployeeDAOImpl class there are two methods one for inserting records and one for finding an employee. Note that Spring jdbcTemplate is used here for data access. In the insertEmployee() method there are two insert queries one for inserting employee record and another one for address of the employee. If this method is running in a transaction and some thing goes wrong while inserting address record, employee record which is already inserted should also roll back.

EmployeeService.java interface

public interface EmployeeService {
  public Employee getEmployee(int empId);
  public void addEmployee(Employee emp);
}

EmployeeServiceImpl.java

import org.netjs.dao.EmployeeDAO;
import org.netjs.model.Employee;
import org.netjs.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(propagation=Propagation.SUPPORTS,readOnly=true)
public class EmployeeServiceImpl implements EmployeeService {
 @Autowired
 private EmployeeDAO empDAO;

 @Override
 public Employee getEmployee(int empId) {
  return empDAO.findEmployee(empId);
 }

 @Override
 @Transactional(propagation=Propagation.REQUIRED,readOnly=false)
 public void addEmployee(Employee emp) {
  empDAO.insertEmployee(emp);
 }
}

As far as the Spring transaction management example goes this is the class where all the transaction related activities happen. As you can see @Transactional annotation is used for declarative transaction. For the whole class transaction management setting is to support transaction if exists and read only optimizations should be applied. In the method addEmployee() transaction settings are overridden and for this method transaction is required and read only is false. Default settings are used for roll back of the transaction where the roll back happens if RunTime exception is thrown.

Also notice the convenience of using Spring declarative transaction. You don’t need to write with in the code where transaction starts, where it ends and when to roll back, you just have to declare the transaction settings for the method and the Spring transaction management will take care of all the boiler plate code for transaction.

XML configuration for the Spring transaction management example

Here is the XML configuration for the example (appContext.xml).

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context.xsd
  http://www.springframework.org/schema/tx 
  http://www.springframework.org/schema/tx/spring-tx.xsd">
    
  <context:component-scan base-package="org.netjs.serviceImpl, org.netjs.DAOImpl" />
  <!--  For reading properties files --> 
  <context:property-placeholder location="classpath:config/db.properties" />
    
  <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
    <property name="driverClassName" value = "${db.driverClassName}" />
    <property name="url" value = "${db.url}" />
    <property name="username" value = "${db.username}" />
    <property name="password" value = "${db.password}" />
    <property name="initialSize" value = "${pool.initialSize}" />
  </bean>
  <!--  Transaction Manager --> 
  <bean id="txManager" class= "org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
  </bean>
  <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
    <property name="dataSource" ref="dataSource"></property>  
  </bean>  
  <tx:annotation-driven proxy-target-class="true" transaction-manager="txManager" />
</beans>

In the XML, Spring transaction management related configuration is listed below-

  1. You need to define the correct Transaction manager implementation class which in case of JDBC is org.springframework.jdbc.datasource.DataSourceTransactionManager.
  2. <tx:annotation-driven/> tag is required to let Spring container know that annotation is used for transaction.
  3. Internally @Transactional annotation uses AOP proxies and proxy-target-class attribute controls what type of transactional proxies are created for classes annotated with the @Transactional annotation. If the proxy-target-class attribute is set to true, then class-based proxies are created. If proxy-target-class is false or if the attribute is omitted, then standard JDK interface based proxies are created.
  4. xmlns:tx="http://www.springframework.org/schema/tx" is needed for tx namespace.
  5. Apart from that Datasource and JDBCTemplate are defined for connecting to DB and executing queries.
To run the Spring transaction management example you can use the following class.
public class App {

 public static void main(String[] args) {
   ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
         ("appcontext.xml");   
   EmployeeService empService = context.getBean("employeeServiceImpl", EmployeeServiceImpl.class); 
   empService.addEmployee(createEmployee());
   context.registerShutdownHook();   
 }
 
 // Method to create Employee object
 private static Employee createEmployee(){
  Employee emp = new Employee();
  Address addr = new Address();
  emp.setEmpId(101);
  emp.setEmpName("John");
  emp.setAge(25);
  // same as employee ID
  addr.setId(emp.getEmpId());
  addr.setAddrLine("Hunters Lane");
  addr.setCity("Princeton");
  emp.setAddress(addr);
  return emp;
 }
}

Output

INFO: Loading XML bean definitions from class path resource [appcontext.xml]
Aug 03, 2018 2:11:56 PM org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
INFO: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
Employee record inserted
Employee address record inserted
Aug 03, 2018 2:11:58 PM org.springframework.context.support.AbstractApplicationContext doClose

For checking that full transaction is rolled back or not, you can give some value while inserting address record which causes error. That should roll back the insertion to employee record too.

That's all for this topic Spring Transaction Management Example - @Transactional Annotation and JDBC. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Data Access in Spring Framework
  2. Spring NamedParameterJdbcTemplate Insert, Update And Delete Example
  3. Autowiring Using Annotations in Spring
  4. Autodiscovery of Bean Using componenent-scan in Spring
  5. Spring Java Configuration Example Using @Configuration

You may also like-

  1. Using Spring Profiles to Switch Environment
  2. Difference Between component-scan And annotation-config in Spring
  3. Excluding Bean From Autowiring in Spring
  4. registerShutdownHook() Method in Spring Framework
  5. Invoking Getters And Setters Using Reflection - Java Program
  6. Deadlock in Java Multi-Threading
  7. BigDecimal in Java
  8. YARN in Hadoop

Wednesday, May 20, 2020

Spring Transaction Attributes - Propagation And Isolation Level Settings

When you declare a transaction in Spring transaction management you can define certain attributes for that transaction. These attributes define how the transaction will function.

Spring transaction attributes

Following attributes define the Spring transaction settings-

  1. Propagation
  2. Isolation level
  3. Time out
  4. Read only
  5. Roll back

Propagation settings in Spring transaction

Propagation behavior decides how a method will work in a transaction context. Transaction management in Spring framework defines seven propagation settings. These propagation settings are defined as final static int in org.springframework.transaction.TransactionDefinition interface.

  • PROPAGATION_REQUIRED- This propagation setting in Spring transaction management means that the method runs in a current transaction if exists. A new transaction is created if none exists.
  • PROPAGATION_REQUIRES_NEW- This propagation setting creates a new transaction, suspending the current transaction if one exists.
  • PROPAGATION_MANDATORY- This setting means that the method must run within a transaction. An exception is thrown if no current transaction exists.
  • PROPAGATION_SUPPORTS- This propagation setting supports a current transaction if exists and run with in it; if no transaction exists then the method executes non-transactionally.
  • PROPAGATION_NOT_SUPPORTED- This propagation setting means that the method doesn't support a transaction. If a transaction exits it is suspended when the method is executed.
  • PROPAGATION_NEVER- This propagation setting doesn't support a transaction. An exception is thrown if transaction exists.
  • PROPAGATION_NESTED- This propagation setting means that the method runs in a nested transaction if there is an existing transaction. If no transaction exists then this setting behaves like PROPAGATION_REQUIRED.

Isolation levels in Spring transaction

This property defines the extent to which this transaction is isolated from the work of other concurrent transactions. Before going into isolation levels defined by Spring transaction management, let’s see what problems may occur due to concurrent transactions.

Dirty read- This situation occurs when a transaction reads the data that is written but not committed by another transaction. As example Transaction T1 reads a row that is updated by Transaction T2 but not yet committed. Later T2 is rolled back which means T1 has read the data which is not valid now.

Non-repeatable reads- This scenario occurs when a transaction reads the same data twice and gets a different value every time. As example transaction T1 reads a row, another transaction T2 updates the same row and commits. T1 reads the same row again and gets a different value.

Phantom reads- In this scenario a transaction executes the same query to read a set of rows and gets additional set of rows in different executions. As example Transaction T1 executes a query to fetch some rows based on some condition, transaction T2 inserts rows that satisfies that condition. T1 runs the query again and gets the additional rows in next execution of the same query.

To mitigate the problems because of these scenarios Spring transaction management defines isolation levels to keep a transaction isolated from other concurrent transactions. Isolation levels as defined in Spring transaction management are as follows, these isolation level settings are defined as final static int in org.springframework.transaction.TransactionDefinition interface.
  • ISOLATION_DEFAULT- This setting means that the default isolation level of the underlying datastore is used.
  • ISOLATION_READ_UNCOMMITTED- This level allows a row changed by one transaction to be read by another transaction before any changes in that row have been committed. Using this setting means that dirty reads, non-repeatable reads and phantom reads can occur.
  • ISOLATION_READ_COMMITTED- This isolation level prohibits a transaction from reading a row with uncommitted changes in it. Using this setting means non-repeatable reads and phantom reads can occur only dirty reads are prevented.
  • ISOLATION_REPEATABLE_READ-This level prohibits a transaction from reading a row with uncommitted changes in it, and it also prohibits the situation where one transaction reads a row, a second transaction alters the row, and the first transaction re-reads the row, getting different values the second time. Using this setting means dirty reads and non-repeatable reads are prevented, phantom reads can occur.
  • ISOLATION_SERIALIZABLE- Using this isolation level means dirty reads, non-repeatable reads and phantom reads all are prevented.

Time out

You can define a time interval in seconds for the transaction to finish. If a transaction keeps running for a long time rather than keep on waiting for transaction to finish, you can provide time out in seconds. Transaction will automatically roll back after those many seconds are elapsed and it has not finished.

Note that timeout settings will not get applied unless an actual new transaction gets started. As only PROPAGATION_REQUIRED, PROPAGATION_REQUIRES_NEW and PROPAGATION_NESTED can cause that, it usually doesn't make sense to specify those settings in other cases.

Read only

By using read only property with the transaction you indicate that the transaction will only read the data won’t modify it. This property provides a chance to optimize transaction.

Roll back

Using this setting you can define for which exceptions transaction has to be rolled back. By default, transactions are rolled back only on runtime exceptions. Using roll back property you can provide specific exceptions (both checked exceptions and runtime exceptions) for which transaction has to be rolled back.

You can even define the no roll back rules specifying the exceptions for which the transaction should not be rolled back.

That's all for this topic Spring Transaction Attributes - Propagation And Isolation Level Settings. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring Transaction Management JDBC Example Using @Transactional Annotation
  2. Select Query Using NamedParameterJDBCTemplate in Spring Framework
  3. Transaction in Java-JDBC
  4. Connection Pooling With Apache DBCP Spring Example
  5. Spring Web MVC Tutorial

You may also like-

  1. How to Inject Prototype Scoped Bean in Singleton Bean
  2. registerShutdownHook() Method in Spring Framework
  3. Run Time Injection Using Spring Expression Language(SpEL)
  4. Using Conditional Annotation in Spring Framework
  5. How to Create Password Protected Zip File in Java
  6. ThreadLocal Class in Java
  7. Type Erasure in Java Generics
  8. Uber Mode in Hadoop

Monday, May 18, 2020

Transaction Management in Spring

This post gives an overview of Spring transaction management, how abstraction is achieved in Spring transaction and how to do programmatic transaction management or declarative transaction management in Spring.


What is transaction

In an application transaction is a sequence of events with all or none proposition. That is either all the events participating in the transaction should happen or none. Transaction demarcates the boundaries and all the statements with in those boundaries are bound by all or none proposition and executed as a single unit of work.

Problems with managing transactions

If you manage transaction on your own or use EJB container managed transaction you choose the transaction as per your requirement i.e. if your using JDBC then you choose the transaction management API for JDBC, for Hibernate you will choose the hibernate transaction management API and for Application server with global transaction you will go with JTA (Java transaction API).

With this approach, if you are using global transactions, where you have multiple transactional resources (like relational databases and message queues) you will manage transaction through JTA.

If you are using local transactions (like a transaction associated with a JDBC connection) you will use JDBC transaction management API. Problem with local transactions is that they cannot work across multiple transactional resources. For example, code that manages transactions using a JDBC connection cannot run within a global JTA transaction. Another problem with local transactions is that they are invasive i.e. you will have all transaction code with in your code.

As example with JDBC transaction you will have something like following in your code.

try{
 connection.setAutoCommit(false);

 statements that are part of transaction
 ---
 ---

 connection.commit(); // for committing transaction
}catch(SQLException exp){
 // transaction rollback
 connection.rollback();
}

Transaction Management in Spring

Spring Framework provides a consistent abstraction for transaction management. Spring transaction management acts as an abstract layer hiding the underlying transaction management API thus providing a consistent programming model across different transaction APIs such as Java Transaction API(JTA), JDBC, Hibernate, and Java Persistence API (JPA).

With Spring transaction management you write your code once and it can be used in different transaction management strategies in different environments.

Spring transactions are also a significant improvement over the EJB transactions as you can use POJOs with Spring transactions. You don’t even need an Application server for Spring transactions unless you are using distributed transactions in which case you need JTA capabilities.

How abstraction is achieved in Spring transaction management

Abstraction in Spring transaction management is achieved through org.springframework.transaction.PlatformTransactionManager interface.

public interface PlatformTransactionManager {
 TransactionStatus getTransaction(TransactionDefinition definition)
             throws TransactionException;
 void commit(TransactionStatus status) throws TransactionException;
 void rollback(TransactionStatus status) throws TransactionException;
}

In the interface, getTransaction() method returns a TransactionStatus object which represents the status of a transaction, it might represent a new transaction or an existing transaction if a matching transaction exists. The parameter passed in getTransaction() method is an instance of TransactionDefinition.

TransactionDefinition defines the properties of the Spring transaction, which are as follows.

  • Propagation- Defines the propagation behavior of the transaction. For example you can specify a behavior so that code can continue running in the existing transaction or the existing transaction can be suspended and a new transaction created.
  • Isolation- This property defines the extent to which this transaction is isolated from the work of other transactions. For example, can this transaction see uncommitted writes from other transactions?
  • Timeout- How long this transaction runs before timing out and being rolled back automatically by the underlying transaction infrastructure.
  • Read-only status- A read-only transaction can be used when your code reads but does not modify data.

Refer Spring Transaction Attributes- Propagation And Isolation Level Settings to know about the various propagation and isolation level settings in the Spring transaction management.

Defining Transaction manager in Spring transactions

As we have seen it is the PlatformTransactionManager through which the transaction is abstracted in Spring transaction management but you do need to define the correct PlatformTransactionManager implementation.

PlatformTransactionManager implementations normally require knowledge of the environment in which they work: JDBC, JTA, Hibernate, and so on. Following are the implementation classes for different environments.

PlatformTransactionManager implementations in Spring framework

  • DataSourceTransactionManager- PlatformTransactionManager implementation for a single JDBC DataSource.
  • HibernateTransactionManager- PlatformTransactionManager implementation for a single Hibernate SessionFactory.
  • JmsTransactionManager- PlatformTransactionManager implementation for a single JMS ConnectionFactory.
  • JpaTransactionManager- PlatformTransactionManager implementation for a single JPA EntityManagerFactory.
  • JtaTransactionManager- PlatformTransactionManager implementation for JTA, delegating to a backend JTA provider.
  • WebLogicJtaTransactionManager- Special JtaTransactionManager variant for BEA WebLogic (9.0 and higher).
  • WebSphereUowTransactionManager- WebSphere-specific PlatformTransactionManager implementation that delegates to a UOWManager instance
Here are some examples showing how TransactionManager can be defined for different environments.

TransactionManager For JDBC in Spring

Defined by having a reference to the defined DataSource.

<bean id="txManager" class=
"org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"/>
</bean>

TransactionManager For Hibernate in Spring

<bean id="txManager" class=
"org.springframework.orm.hibernate5.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory"/>
</bean>

TransactionManager For JPA in Spring

<bean id="txManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
  <propertyname="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

TransactionManager For JTA in Spring

<bean id="txManager" class=
"org.springframework.transaction.jta.JtaTransactionManager" />

Spring Transaction management types

Spring Transaction management has support for both programmatic transaction management and declarative transaction management.

Programmatic transaction management

Spring Framework provides two means of programmatic transaction management-

  • Using TransactionTemplate.
  • Using a PlatformTransactionManager implementation directly.

Mostly declarative transaction that too using annotation is used so we'll focus on that. If you want to use TransactionTemplate then you can configure it as follows by providing the reference of the Transaction manager.

<propertyname="transactionTemplate">
<bean class="org.springframework.transaction.support.
TransactionTemplate">
<property name="transactionManager"
ref="txManager" />
</bean>
</property>

Declarative transaction management in Spring

By using Declarative transaction for Spring transaction management you keep transaction management separate from the business code. You can define declarative transactions using annotations or XML based configuration using AOP.

The annotation used for Declarative transaction management is @Transactional annotation. You can place the @Transactional annotation before an interface definition, a method on an interface, a class definition, or a public method on a class.

To make Spring framework aware of the @Transactional annotation you will have to define <tx:annotation-driven/> element in your XML configuration.

<tx:annotation-driven transaction-manager="txManager"/>

If you using Java configuration then you can enable @Transactional annotation support by adding @EnableTransactionManagement to your config class.

@Configuration
@EnableTransactionManagement
public class AppConfig{
    ...
    ...
}

Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Transactional annotation, as opposed to annotating interfaces.

@Transactional settings in Spring framework

You can provide transaction properties like propagation behavior, isolation level along with @Transactional annotation. Full list of the properties of the @Transactional annotation are as follows-

  • propagation- Optional propagation setting.
  • isolation- Optional isolation level. Only applicable to propagation REQUIRED or REQUIRES_NEW.
  • timeout- Optional transaction timeout. Only applicable to propagation REQUIRED or REQUIRES_NEW. Defined in seconds using an int value.
  • readOnly- Read/write vs. read-only transaction. Only applicable to REQUIRED or REQUIRES_NEW.
  • rollbackFor- Optional array of exception classes that must cause rollback.
  • rollbackForClassName- Optional array of names of exception classes that must cause rollback.
  • noRollbackFor- Optional array of exception classes that must not cause rollback.
  • noRollbackForClassName- Optional array of names of exception classes that must not cause rollback.
The default @Transactional settings are as follows:
  • Propagation setting is PROPAGATION_REQUIRED.
  • Isolation level is ISOLATION_DEFAULT.
  • Transaction is read/write.
  • Transaction timeout defaults to the default timeout of the underlying transaction system, or to none if timeouts are not supported.
  • Any RuntimeException triggers rollback, and any checked Exception does not.

Example using @Transactional annotation

@Transactional(readOnly = true, propagation=Propagation.SUPPORTS)
public class TestService implements FooService {
 public Foo getValue(String Id) {
  // do something
 }
 // these settings have precedence for this method
 @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW, timeout=60, rollbackFor=ValueNotFoundException.class)
 public void updateValue(Person person) {
  // do something
 }
}

Here at the class level TestService class is annotated with @Transactional annotation which is for all the methods in the class that all the methods will support transaction and will be read only. Method updateValue overrides it by having its own @Transactional annotation which requires a new transaction, read only is false and transaction is rolled back if ValueNotFoundException is thrown.

That's all for this topic Transaction Management in Spring. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring Transaction Management JDBC Example Using @Transactional Annotation
  2. Data Access in Spring Framework
  3. Insert\Update Using NamedParameterJDBCTemplate in Spring Framework
  4. Spring MVC Form Example With Bean Validation
  5. Spring Batch Processing Using JDBCTemplate batchUpdate() Method

You may also like-

  1. Difference Between component-scan And annotation-config in Spring
  2. How to Inject Null And Empty String Values in Spring
  3. Internationalization (i18n) Using MessageSource in Spring
  4. Circular Dependency in Spring Framework
  5. Heap Memory Allocation in Java
  6. Stream API in Java 8
  7. Creating Custom Exception Class in Java
  8. Installing Hadoop on a Single Node Cluster in Pseudo-Distributed Mode

Saturday, May 16, 2020

Interface Static Methods in Java

Java 8 has added support for interface default methods as well as interface static methods which is one of the important change in Java 8 along with the addition of lambda expressions and stream API. In this post we'll see how to use interface static methods in Java and what are the rules for using them


Static method in Java interface

Like static methods in a class, now we can write static method in interfaces too. Static methods in an interface can be called independently of any object just like how static methods are called in a class.

General form of calling the interface static method

Static methods in an interface are called by using the interface name preceding the method name.

InterfaceName.staticMethodName;

Java interface static method example

public interface MyInterface {
 int method1();
 // default method, providing default implementation
 default String displayGreeting(){
    return "Hello from MyInterface";
 }
 //static method
 static int getDefaultAmount(){
    return 0;
 }
}
public class MyClass{ 
  public static void main(String[] args) { 
    int num = MyInterface.getDefaultAmount();
    System.out.println("num " + num);
  } 
}

Output

num 0

In the example code interface MyInterface has one static method getDefaultAmount(). Note that MyClass is not even implementing the interface MyInterface still static method of the MyInterface can be called from MyClass using the call MyInterface.getDefaultAmount();. This is because, no implementation or reference of the interface is required to call the static method.

Interface static methods are not inherited

Static interface methods are not inherited by-

  • Implementing classes
  • Extending interfaces

Here interface B is extending mentioned interface MyInterface, but it can not access the static method of interface MyInterface.

interface B extends MyInterface{ 
  default String displayGreeting(){
    B.getDefaultAmount(); // Compiler Error 
    return "Hello from MyInterface";
  }
}

Same way even if MyClass implements MyInterface still it can not access static method of MyInterface, either by using the class name or by using the object reference.

public class MyClass implements MyInterface{
  // provides implementation for the non-default method
  // of the interface
  @Override
  public int method1() {
    return 10;
  }
  //Overriding the default method of MyInterface
  public String displayGreeting(){
    return MyInterface.super.displayGreeting();
  }
 
  public static void main(String[] args) {
    MyInterface myInt = new MyClass();

    int num = MyInterface.getDefaultAmount();
    System.out.println("num " + num);
    MyClass.getDefaultAmount(); // Compiler error
    myInt.getDefaultAmount();// Compiler error
  } 
}

Hiding interface static method

Though implementing class can't provide implementation for the static methods of an interface but the implementing class can hide the interface static method in Java by providing method with same signature in the implementing class.

public interface MyInterface {
  int method1();
  // default method, providing default implementation
  default String displayGreeting(){
     return "Hello from MyInterface";
  }
  static int getDefaultAmount(){
     return 0;
  }
}
Implementing class
public class MyClass implements MyInterface{
  // provides implementation for the non-default method
  // of the interface
  @Override
  public int method1() {
    return 10;
  }
  //Overriding the default method of MyInterface
  public String displayGreeting(){
    return MyInterface.super.displayGreeting();
  }
  // static method
  public static int getDefaultAmount(){
    return 5;
  }
 
  public static void main(String[] args) {
    MyInterface myInt = new MyClass();

    int num = MyInterface.getDefaultAmount();
    System.out.println("num - Interface " + num);
    System.out.println("num - Class " + MyClass.getDefaultAmount());  
  } 
}

Output

num - Interface 0
num - Class 5

Here getDefaultAmount() method is provided in the MyClass class also which hides the interface static method.

Advantages of Java interface static methods

  • Interface static methods can be used for providing utility methods.
  • With Interface static methods we can secure an implementation by having it in static method as implementing classes can't override them. Though we can have a method with same signature in implementing class but that will hide the method won't override it.

That's all for this topic Interface Static Methods in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Basics Tutorial Page


Related Topics

  1. Marker Interface in Java
  2. Difference Between Abstract Class And Interface in Java
  3. PermGen Space Removal in Java 8
  4. Lambda Expressions in Java 8
  5. Core Java Basics Interview Questions And Answers

You may also like-

  1. Functional Interface Annotation in Java
  2. Java Stream API Examples
  3. New Date And Time API in Java 8
  4. fail-fast Vs fail-safe iterator in Java
  5. How HashMap internally works in Java
  6. Java Abstract Class and Abstract Method
  7. Difference Between throw And throws in Java
  8. final Vs finally Vs finalize

Friday, May 15, 2020

Interface Default Methods in Java

Java 8 has added support for default methods as well as static methods to interfaces. In this post we'll talk about interface default methods in Java.


Need for interface default methods in Java

There was a problem with interfaces in Java that they were not open to extension, which means if there was a need to add new method to an interface it would have broken the existing implementations of that interface. Thus it was imperative that all the classes implementing that interface had to provide implementation for the newly added method, even if the method was not needed. Thus Java interfaces were not easy to evolve.

One example that comes to mind is Java MapReduce API for Hadoop, which was changed in 0.20.0 release to favour abstract classes over interfaces, since they are easier to evolve. Which means, a new method can be added to abstract class (with default implementation), with out breaking old implementations of the class.

Default method in Java interface

Java 8 onward it is possible to add default method in Java interfaces too, thus making them easier to evolve. With the addition of default method to an interface, addition of new method, even to an interface will not break the pre-existing code.

Interface default method should be used for backward compatibility. Whenever there is a need to add new methods to an existing interface, default methods can be used so that existing implementing classes don't break and not forced to provide implementation for the newly added methods.

Java Interface Default Method Example

An interface default method in Java is defined the same way a method will be defined in a class. One difference is that in interface, default method is preceded by the keyword default.

public interface MyInterface {
  int method1();
  // default method, providing default implementation
  default String displayGreeting(){
    return "Hello from MyInterface";
  }
}
public class MyClass implements MyInterface{
  // provides implementation for the non-default method
  // of the interface
  @Override
  public int method1() {
    return 10;
  }
  public static void main(String[] args) {
    MyInterface myInt = new MyClass();
    System.out.println("Value " +  myInt.method1());
    // Calls the default method provided by interface itself
    System.out.println("Greeting " + myInt.displayGreeting());
  }
}

Output

Value 10
Greeting Hello from MyInterface

It can be seen that in MyInterface interface there is a default method displayGreeting(). Here implementing class is not overriding and providing its own implementation of the default method thus the default is used.

Implementing class can provide its own implementation of a default method by overriding it. If we use the same interface and class as used above and override the displayGreeting method to change the implementation.

public class MyClass implements MyInterface{
  // provides implementation for the non-default method
  // of the interface
  @Override
  public int method1() {
    return 10;
  }
  //Overriding the default method of MyInterface
  public String displayGreeting(){
    return "Hello from MyClass";
  }
 
  public static void main(String[] args) {
    MyInterface myInt = new MyClass();
    System.out.println("Value " +  myInt.method1());
    // Calls the default method provided by interface itself
    System.out.println("Greeting " + myInt.displayGreeting());
  }
}

Output

Value 10
Greeting Hello from MyClass

It can be seen how output has changed and now the displayGreeting() method of the implementing class is used.

Interface default methods and multiple inheritance issues

With the inclusion of default methods, interfaces may have multiple inheritance issues. Though an interface can't hold state information (interface can't have instance variables), so state information can't be inherited, but behavior in form of default method may be inherited which may cause problems. Let's see it with an example-

Let's assume there are two interfaces A and B and both have default method displayGreeting(). There is a class MyClass which implements both these interfaces A and B.

Now consider the scenarios-

  • What implementation of default method displayGreeting() will be called when MyClass is implementing both interfaces A and B and not overriding the displayGreeting() method.
  • What implementation of displayGreeting() will be called when MyClass is implementing both interfaces A and B and overriding the displayGreeting method and providing its own implementation.
  • If interface A is inherited by interface B, what will happen in that case?

To handle these kinds of scenarios, Java defines a set of rules for resolving default method conflicts.

  • If implementing class overrides the default method and provides its own functionality for the default method then the method of the class takes priority over the interface default methods.
    As Example - If MyClass provides its own implementation of displayGreeting(), then the overridden method will be called not the default method in interface A or B.
  • When class implements both interfaces and both have the same default method, also the class is not overriding that method then the error will be thrown.
    "Duplicate default methods named displayGreeting inherited from the interfaces"
  • In case when an interface extends another interface and both have the same default method, the inheriting interface default method will take precedence. Thus, if interface B extends interface A then the default method of interface B will take precedence.

Use of Super with interface default methods

As stated above when class implements 2 interfaces and both have the same default method then the class has to provide an implementation of its own for the default method otherwise error will be thrown. From the implementing class if you want to call the default method of interface A or interface B, then from the implementation in the class you can call the default method of the specific interface using the super keyword.

Syntax for calling the default method of the specific interface using super is as follows-

InterfaceName.super.methodName();

For example, if you want to call the default method of interface A.

public interface A {
  int method1();
  // default method, providing default implementation
  default String displayGreeting(){
    return "Hello from interface A";
  }
}

interface B{
  // default method, providing default implementation
  default String displayGreeting(){
    return "Hello from Interface B";
  }
}
public class MyClass implements A, B{
  // provides implementation for the non-default method
  // of the interface
  @Override
  public int method1() {
     return 10;
  }
  //Overriding the default method of MyInterface
  public String displayGreeting(){
     return A.super.displayGreeting();
  }
 
  public static void main(String[] args) {
     A myInt = new MyClass();
     System.out.println("Value " +  myInt.method1());
     // Calls the default method provided by interface itself
     System.out.println("Greeting " + myInt.displayGreeting());
  }
}

Output

Value 10
Greeting Hello from interface A

It can be seen from displayGreeting() method of the class, using super, displayGreeting() method of interface A is called here.

Difference between Interface with default method and abstract class in Java

With interfaces also providing default methods the lines between the abstract class and interface blurs a bit in Java. But there are still certain differences between them.

  • Abstract class can have constructor, instance variables but interface can't have any of them.
  • interfaces with default methods also cannot hold state information.

Points to note-

  • With Java 8 interface default methods had been added in order to make interfaces easy to evolve.
  • With interface default method, classes are free to use the default method of the interface or override them to provide specific implementation.
  • With interface default methods there may be multiple inheritance issue if same default method is provided in more than one interfaces and a class is implementing those interfaces.
  • super can be used from the implementing class to invoke the interface default method. It's general form is InterfaceName.super.methodName();
  • Interface default methods don't change the basic traits of interface, interface still can't hold state information, it is still not possible to create an instance of an interface by itself.

That's all for this topic Interface Default Methods in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Basics Tutorial Page


Related Topics

  1. Interface in Java With Examples
  2. Marker Interface in Java
  3. Difference Between Abstract Class And Interface in Java
  4. Private Methods in Java Interface
  5. Core Java Basics Interview Questions

You may also like-

  1. Lambda expressions in Java 8
  2. Try-With-Resources in Java With Examples
  3. Java Stream API Examples
  4. strictfp in Java
  5. covariant return type in Java
  6. How and why to synchronize ArrayList in Java
  7. Java ReentrantLock With Examples
  8. Bean Scopes in Spring With Examples

Wednesday, May 13, 2020

Difference Between @Controller And @RestController Annotations in Spring

In this post we’ll see the difference between @Controller and @RestController annotations in Spring framework.


@Controller annotation in Spring

In a Spring web MVC project generally a view technology like JSP, Freemarker, Thymeleaf is used to render the view. In that case from a Controller method, model is created and a logical view name is returned which is mapped to a view using the configured ViewResolver.

You may also return the object itself from the Controller method, in that case object data is written to the HTTP response body as JSON/XML. For that you need to use the annotation @ResponseBody explicitly which indicates a method return value should be bound to the web response body.

@RestController annotation in Spring

With RESTful web services interchange of data happens mostly as JSON or XML. In case you are writing a Spring REST service you will have to use @ResponseBody annotation along with the @Controller annotation to indicate that the returned object has to be serialized to the response body.

Unlike Spring Web MVC where mostly controller methods return ModelAndView, with Spring REST services it is the object itself which is returned. So Spring framework from version 4 has introduced a convenience annotation @RestController which combines both @Controller and @ResponseBody annotations. In a controller class annotated with @RestController all the @RequestMapping methods assume @ResponseBody semantics by default.

Following two types are same in Spring MVC.

@Controller
@ResponseBody
public class MessageController {
 ..
 ..
}
@RestController
public class MessageController {
 ..
 ..
}

Note that when @ResponseBody annotation is used on a method, return is serialized to the response body through an HttpMessageConverter.

Concrete implementations of the HttpMessageConverter for the main media (mime) types are provided in the Spring framework and are registered by default with the RestTemplate on the client-side and with RequestMethodHandlerAdapter on the server-side. Appropriate implementation of the HttpMessageConverter based on the mime type is chosen for converting the object.

@Controller Vs @RestController in Spring

1- @Controller annotation is used in Spring Web MVC project where model data is rendered using a view.
@RestController is used in RESTful web services where return value (which is mostly an object) is bound to the response body.

2- With classes annotated with @Controller annotation if you want return value to be converted through HttpMessageConverters and written to the response you will have to annotate the class with an extra annotation @ResponseBody or you can annotate individual handler methods with in the controller class with @ResponseBody annotation.
@RestController annotation is the combination of @Controller + @ResponseBody. With @RestController annotation it is the default behavior that the result will be written to the response body.

3- With @Controller annotation you still have that control that you can annotate individual methods with @ResponseBody annotation.
With @RestController annotation all the handler methods of the class write their result to the response body.

@Controller with @ResponseBody Spring MVC example

@Controller
public class MessageController {
 @RequestMapping(value = "/", method = RequestMethod.GET)
 public String showHome(Model model) {
  model.addAttribute(new User());
  model.addAttribute("message", "Spring MVC example");
  return "home";
 }

 @RequestMapping(value = "/getUser/{userId}", method = RequestMethod.GET, produces="application/json")
 @ResponseBody
 public User getUser(@PathVariable("userId") String userId) {  
  return findUserById(userId);
 }

 // Dummy method to find user
 private User findUserById(String userId) {
  System.out.println("User ID " + userId);
  User user = new User();
  user.setUserId(userId);
  user.setFirstName("Leonard");
  user.setLastName("Nimoy");
  return user;
 }
}

As you can see in this controller class first method showHome() is a typical Spring web MVC handler method that returns a logical view name which resolves to home.jsp because of the following configuration.

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/WEB-INF/jsp/" />
  <property name="suffix" value=".jsp" />
</bean>

Second method getUser() is annotated with @ResponseBody annotation. Note that using the produces attribute it is also indicated that the media type is JSON.

You will need to add the following Maven dependency for JSON conversion-

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.9.6</version>
</dependency>

which adds the following jars.

jackson-databind-2.9.6.jar
jackson-annotations-2.9.0.jar
jackson-core-2.9.6.jar

Running it using the URL- http://localhost:8080/springmvc-config/getUser/101 after deployment gives the following result.

@Controller Vs @RestController Spring

@RestController annotation - Spring example

If we have to write the same controller class as a Rest service using @RestController annotation then there is no need to annotate the getUser() method explicitly with the @ResponseBody annotation.

@RestController
public class MessageController { 
 @RequestMapping(value = "/getUser/{userId}", method = RequestMethod.GET, produces="application/json")
 public User getUser(@PathVariable("userId") String userId) {  
  return findUserById(userId);
 }
 
 // Dummy method to find user
 private User findUserById(String userId) {
  System.out.println("User ID " + userId);
  User user = new User();
  user.setUserId(userId);
  user.setFirstName("Leonard");
  user.setLastName("Nimoy");
  return user;
 }
}

That's all for this topic Difference Between @Controller And @RestController Annotations in Spring. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring MVC Redirect Example
  2. Spring Transaction Management Example - @Transactional Annotation and JDBC
  3. Spring Batch Processing With List of Objects in batchUpdate() Method
  4. Spring NamedParameterJdbcTemplate Select Query Example
  5. Spring Java Configuration Example Using @Configuration

You may also like-

  1. Spring Profiles With Examples
  2. How to Inject Null And Empty String Values in Spring
  3. Spring util-namespace Example For Wiring Collection
  4. Injecting Inner Bean in Spring
  5. Difference Between ArrayList And LinkedList in Java
  6. Lambda Expressions in Java
  7. Array in Java With Examples
  8. How to Read And Write Parquet File in Hadoop

Tuesday, May 12, 2020

Spring MVC @RequestParam Annotation Example

In this Spring MVC @RequestParam annotation example we’ll see how request data can be passed to the controller using @RequestParam annotation along with @RequestMapping annotation.

Spring @RequestParam and @RequestMapping annotation

If you are passing request parameters as query parameters, then you can use @RequestParam along with @RequestMapping annotation in the Spring controller method.

For example- /spring-mvc/getUser?userId=101

Here userId is the query parameter that can be retrieved using the @RequestParam annotation.

Spring web MVC example with @RequestParam annotation

In this Spring MVC example we’ll have a JSP (home page) with 3 fields, entered values in these 3 fields are sent as query parameters with in the URL.

home.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Spring MVC tutorial - Home JSP</title>
</head>
<body>
  <div>Message- ${message}</div>
  <form name="userform" action="showUser" method="get">
    <table>
      <tr>
        <td>
          First Name: <input type="text" id="firstName" name="firstName">
        </td>
      </tr>
      <tr>
        <td>
          Last Name: <input type="text" id="lastName" name="lastName">
        </td>
      </tr>
      <tr>
        <td>
          DOB: <input type="text" id="dob" name="dob">
        </td>
      </tr>        
    </table>               
    <input type="submit" value="Submit">
  </form>
</body>
</html>

Spring MVC - Controller class

In the controller class there are two methods. First method showHome() is annotated with RequestMapping value parameter as “/” and returns the logical view name as “home” which results in the display of home.jsp.

Another method showUser() serves to the request where path is “/showUser”. In this method the method parameters are annotated with @RequestParam. The value parameter with in the @RequestParam should match the query parameter name. For example this handler method will serve the requests in the form - /showUser?firstName=Leonard&lastName=Nimoy&dob=1956-05-23

The value of the query parameter will be assigned to the corresponding method parameter.

MessageController.java

import java.time.LocalDate;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class MessageController {
 @RequestMapping(value = "/", method = RequestMethod.GET)
 public String showHome(Model model) {
  model.addAttribute("message", "MVC Example with dynamic URL");
  return "home";
 }
 
 @RequestMapping(value = "/showUser", method = RequestMethod.GET)
 public String showUser(@RequestParam("firstName") String firstName, 
                @RequestParam("lastName") String lastName, 
                @DateTimeFormat(pattern = "yyyy-MM-dd")
                @RequestParam("dob") LocalDate dob,
                Model model) { 

  model.addAttribute("firstName", firstName);
  model.addAttribute("lastName", lastName);
  model.addAttribute("dob", dob);
  return "user";
 }
}

The parameters of the method showUser() which have the values of the query parameters assigned to them are added to the Model. The method returns the logical view name as “user” which is resolved to the view user.jsp.

Note that if method parameter name is same as the query parameter name in the @RequestMapping then the value parameter with @RequestParam is optional. So the same method can also be written as-

@RequestMapping(value = "/showUser", method = RequestMethod.GET)
public String showUser(@RequestParam String firstName, 
             @RequestParam String lastName, 
             @DateTimeFormat(pattern = "yyyy-MM-dd")
             @RequestParam LocalDate dob,
             Model model) {

 ...
 ...
}

user.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Spring MVC tutorial - User</title>
</head>
<body>
<div>First Name: ${firstName}</div>
<div>Last Name: ${lastName}</div>
<div>DOB: ${dob}</div>
</body>
</html>

Home page

Spring MVC with @RequestParam

User page

Spring MVC with RequestParam annotation

Default value for RequestParam parameters in Spring MVC

If you want to provide default value for the RequestParam parameters if the query parmeters are not there in the request then you can use defaultValue attribute of the @RequestParam. The default value is used as a fallback when the request parameter is not provided or has an empty value.

@RequestMapping(value = "/showUser", method = RequestMethod.GET)
public String showUser(
  @RequestParam(value="firstName", defaultValue="Test") String firstName, 
  @RequestParam(value="lastName", defaultValue="User") String lastName, 
  @DateTimeFormat(pattern = "yyyy-MM-dd")
  @RequestParam(value="dob", defaultValue="2000-01-01") LocalDate dob,
  Model model) { 
 ...
 ...
}

required attribute in Spring @RequestParam annotation

You can set whether the parameter is required or not using required attribute. Default value for the required attribute is true, which means an exception is thrown if the parameter is missing in the request. By setting required as false null value is assigned if the parameter is not present in the request.

For example if you want to make DOB as optional.

@RequestMapping(value = "/showUser", method = RequestMethod.GET)
public String showUser(
  @RequestParam(value="firstName", defaultValue="Test") String firstName, 
  @RequestParam(value="lastName", defaultValue="User") String lastName, 
  @DateTimeFormat(pattern = "yyyy-MM-dd")
  @RequestParam(value="dob", required=false) LocalDate dob,
  Model model) {
 ...
 ...
}

That's all for this topic Spring MVC @RequestParam Annotation Example. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring Web MVC Tutorial
  2. Spring MVC Example With @PathVaribale - Creating Dynamic URL
  3. Spring MVC File Download Example
  4. Spring MVC Redirect Example
  5. Spring Transaction Management JDBC Example Using @Transactional Annotation

You may also like-

  1. Internationalization (i18n) Using MessageSource in Spring
  2. @Resource Annotation in Spring Autowiring
  3. Spring Bean Life Cycle
  4. Bean Definition Inheritance in Spring
  5. Difference Between ArrayList And CopyOnWriteArrayList in Java
  6. Java ReentrantLock With Examples
  7. this Keyword in Java With Examples
  8. Checking Number Prime or Not Java Program

Saturday, May 9, 2020

Java Object Cloning - clone() Method

In this post we'll see what is Object cloning in java and what is shallow copy and deep copy in reference to Java object cloning.

In Java if you assign an object variable to another variable the reference is copied which means both variable will share the same reference. In this case any change in one object variable will be reflected in another.

For example, if there is a class Test and you create an object of that class and then assign that reference to another object variable.

Test obj1 = new Test();
Test obj2 = obj1;

Here both obj1 and obj2 will have the same reference.


Java Object cloning

What is the option then if you want to quickly create an object using the existing object in such a way that you get a new instance (reference is not shared) with the same content for the fields in the new object as in existing object.

That’s when you can use clone() method which creates an exact copy of the existing object. Then you can modify the cloned object without those modification reflecting in original object (Well we’ll go into shallow copy and deep copy a little later).

clone() method in Java

clone() method is defined as protected in the Java Object class which you must override as public in any derived classes that you want to clone.

Signature of clone method in Object class

protected native Object clone() throws CloneNotSupportedException;

Process of object cloning in Java

There are two required steps if you want to clone any object.

  1. You need to call clone() method of the Object class or provide your own implementation by overriding the clone() method in your class.
  2. Your class, whose object you want to clone, must implement Cloneable interface which is part of java.lang package. Not implementing Cloneable interface will result in CloneNotSupportedException exception being thrown when clone method is called.

Here note that Cloneable interface is a marker interface and defines no members of its own.

Object cloning in Java example

When cloning an object in Java you need to call clone() method of the Object class. You can do it from a method or you can override clone() method of the Object class and then call the clone() method of the super class (Object class).

Scenario 1- Calling clone() method from a method

Here we have a class Test which implements Cloneable interface and it has a method cloneIt() which calls the clone() method of the Object class.

Class Test

public class Test implements Cloneable{
  int a;
  float f;
 
 Test cloneIt(){
  Test test = null;
  try {
   // Calling clone() method of Object class
   test = (Test)super.clone();
  } catch (CloneNotSupportedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return test;
  
 }
}

CloningDemo class

public class CloningDemo {

 public static void main(String[] args) {
  Test t1 = new Test();
  t1.a = 10;
  t1.f = 13.4F;
  // Calling method to clone
  Test t2 = t1.cloneIt();
  System.out.println("t1.a " + t1.a + " t1.f " + t1.f);
  
  System.out.println("t2.a " + t2.a + "t2.f " + t2.f);

  if(t1 != t2){
   System.out.println("Different instances");
  }else{
   System.out.println("Same instances");
  }
 }
}

Output

t1.a 10 t1.f 13.4
t2.a 10t2.f 13.4
Different instances

Here you can see that Test class object t1 is cloned and a new instance t2 is created, in the code even reference equality is checked and you can see that the reference is not shared and both are indeed different instances.

Points to note

Some of the points to note from this code –

  1. Class whose object has to be cloned should implement Cloneable interface, otherwise java.lang.CloneNotSupportedException exception will be thrown.
  2. clone() method is a protected method in Object class, since all the classes inherit from Object class so you can call the protected method of the super class.
  3. While cloning bitwise copy of the object is created.

Scenario 2 – Overriding clone method

Another way to provide object cloning functionality is to override the clone() method in the class in that case it has to be a public method in order to be accessible.

If we change the classes used in the above example to have overridden clone method and calling that clone method then the structure will be as follows–

Test class

public class Test implements Cloneable{
 int a;
 float f;
 // Override clone method
 public Object clone(){
  Object obj = null;
  try {
   // Calling clone() method of Object class
   obj = super.clone();
   } catch(CloneNotSupportedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
  return obj;
 }
}

CloningDemo class

public class CloningDemo {

 public static void main(String[] args) {
  Test t1 = new Test();
  t1.a = 10;
  t1.f = 13.4F;
  // Call clone method
  Test t2 = (Test)t1.clone();
  System.out.println("t1.a " + t1.a + " t1.f " + t1.f);
  
  System.out.println("t2.a " + t2.a + " t2.f " + t2.f);
  
  if(t1 != t2){
   System.out.println("Different instances");
  }else{
   System.out.println("Same instances");
  }
 }
}

Output

t1.a 10 t1.f 13.4
t2.a 10 t2.f 13.4
Different instances

Advantages of object cloning

If you have an object, creation of which using the usual way is costly; as example if you have to call DB in order to get data to create and initialize your object. In that scenario rather than hitting DB every time to create your object you can cache it, clone it when object is needed and update it in DB only when needed.

Actually there is a design pattern called prototype design pattern which suggests the same approach.

Shallow copy - Java object cloning

In the above examples only primitive types are used so there is no problem, if you change any primitive value that won’t reflect in other object.

What if there is another object reference in your class? As already mentioned when you clone an object all the values for the fields are copied to the cloned object. Since Java is pass by value, if the field value is a reference to an object (a memory address) it copies that reference to the field of the cloned object. In that case referenced field is shared between both objects and any change made to the referenced field will be reflected in the other object too.

This process of cloning when the field values are copied to the new object is known as shallow copy. Shallow copies are simple to implement and typically cheap, as they can be usually implemented by simply copying the bits exactly.

Deep Copy - Java object cloning

If you don’t want references of object being copied during the cloning process then option is deep copy. When a deep copy is done objects referenced by the cloned object are distinct from those referenced by original object, and independent.

Deep copies are more expensive, as you need to create additional objects, and can be substantially more complicated, due to references possibly forming a complicated graph.

That's all for this topic Java Object Cloning - clone() Method. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Basics Tutorial Page


Related Topics

  1. Serialization and Deserialization in Java
  2. SerialVersionUID And Versioning in Java Serialization
  3. Java Nested Class And Inner Class
  4. Marker interface in Java
  5. Core Java Basics Interview Questions And Answers

You may also like-

  1. instanceof Operator in Java With Examples
  2. BigDecimal in Java With Examples
  3. Java split() Method - Splitting a String
  4. final Vs finally Vs finalize in Java
  5. Parallel Stream in Java Stream API
  6. @FunctionalInterface Annotation in Java
  7. Deadlock in Java Multi-Threading
  8. Java Program to Find The Longest Palindrome in a Given String