Friday, July 31, 2020

Difference Between StackOverflowError and OutOfMemoryError in Java

Differences between StackOverflowError and OutOfMemoryError in Java is a frequently asked Java interview question. You may also encounter one of these errors in your application. Before going into StackOverflowError Vs OutOfMemoryError let’s get some background about these errors.


StackOverflowError in Java

Whenever you run any Java program even if you don’t explicitly create any thread a main thread is started and that thread runs the program.

For each thread JVM creates a stack, whenever any method is invoked a new frame is created and pushed into the JVM stack for the thread. Each frame stores data corresponding to the invoked method including local variables, operand stack and a reference to the run-time constant pool and reference to exception table.

Once the method execution is completed corresponding stack frame is popped out of the stack.

JVM throws StackOverflowError if the stack memory requirement of any method exceeds the permitted stack memory size. A very common scenario where you may see StackOverflowError is when you have a recursive method with no terminating condition. For example following program that calculates factorial of a number using recursive method call. Since there is no exit condition defined so recursive method call never ends resulting in StackOverflowError.

public class StackOFErrorExp {
  public static void main(String[] args) {
    double factorialResult = factorial(1000);
    System.out.println(factorialResult);
  }
  private static int factorial(int i) {
    /*
     * if (i == 0 || i == 1 ) '
     *  return 1;
     */
    return i * factorial(i - 1);
  }
}

OutOfMemoryError in Java

In Java, memory for each object, for arrays and for instance variables (variables at class level not method level) is created on the heap. When there are no references to an object that object is garbage collected thus clearing the heap memory.

If you try to create an object or array that tries to take more memory than the allocated heap memory or there are a lot of objects in heap that are still referenced so can’t be garbage collected and JVM tries to allocate heap memory for a new object JVM throws java.lang.OutOfMemoryError because there is no sufficient heap memory.

Here is an example of java.lang.OutOfMemoryError where objects are added to an ArrayList in an infinite loop. Since objects stored to the List are not garbage collected so heap memoery will finally run out of memory resulting in OutOfMemoryError.

public class OutofMemoryExp {
  public static void main(String[] args) {
    List list = new ArrayList<>();
    int i = 0;
    // results in indefinite loop
    while(true) {
      i++;
      list.add(i * 1000000);
    }  
  }
}

Output

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
 at java.base/java.util.Arrays.copyOf(Arrays.java:3721)
 at java.base/java.util.Arrays.copyOf(Arrays.java:3690)
 at java.base/java.util.ArrayList.grow(ArrayList.java:237)
 at java.base/java.util.ArrayList.grow(ArrayList.java:242)
 at java.base/java.util.ArrayList.add(ArrayList.java:485)
 at java.base/java.util.ArrayList.add(ArrayList.java:498)
 at org.netjs.examples.OutofMemoryExp.main(OutofMemoryExp.java:14)

StackOverflowError Vs OutOfMemoryError in Java

  1. StackOverflowError is thrown when there is no sufficient stack space for storing method data.
    OutOfMemoryError is thrown when no sufficient heap space left for creating new objects or requested array size is more than heap memory.
  2. StackOverflowError happens when you have Recursive methods with out terminating condition.
    OutOfMemoryError happens when new objects can’t be allocated on the heap as existing objects still have references so can’t be garbage collected.
  3. In order to avoid StackOverflowError ensure that methods are finishing their execution and corresponding stack memory is freed.
    In order to avoid OutOfMemoryError ensure that there are nto references to objects which you don’t need anymore so that such objects can be garbage collected freeing heap memory in the process.

That's all for this topic Difference Between StackOverflowError and OutOfMemoryError in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Difference Between Checked And Unchecked Exceptions in Java
  2. Difference Between throw And throws in Java
  3. final Vs finally Vs finalize in Java
  4. java.lang.ClassCastException - Resolving ClassCastException in Java
  5. java.lang.UnsupportedClassVersionError - Resolving UnsupportedClassVersionError in Java

You may also like-

  1. Java Exception Handling Interview Questions
  2. Array in Java With Examples
  3. varargs in Java
  4. Type Erasure in Java Generics
  5. Pre-defined Functional Interfaces in Java
  6. Linear Search (Sequential Search) Java Program
  7. Installing Anaconda Distribution On Windows
  8. Different Bean Scopes in Spring

Wednesday, July 29, 2020

Writing a File Asynchronously Java Program

In this post we’ll see how to write a file asynchronously in Java using java.nio.channels.AsynchronousFileChannel class added in Java 7. Using AsynchronousFileChannel class you can create an asynchronous channel for reading, writing, and manipulating a file.

Opening an Asynchronous channel

Whether you are reading or writing a file asynchronously first thing you need to do is to create an asynchronous channel. For that you need to use static open() method of the AsynchronousFileChannel class which opens or creates a file for reading or writing, returning an asynchronous file channel to access the file.

Following code snippet shows how you can create an asynchronous file channel for writing to a file.

Path path = Paths.get("F:\\netjs\\WriteFile.txt");
AsynchronousFileChannel asyncFileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE)

Writing file asynchronously using AsynchronousFileChannel class

For writing a file asynchronously there are two versions of write() method in the AsynchronousFileChannel class.

  1. write() method that writes the passed buffer to the file and returns a Future representing the result of the write operation.
  2. write() method where you pass CompletionHandler instance as an argument.

We’ll see examples of of both of these ways to write a file asynchronously to have a better idea.

Writing to a file asynchronously in Java

1. In the first Java program we’ll use the write method that returns a Future.

Future<Integer> write(ByteBuffer src, long position)- This method writes a sequence of bytes to this channel from the passed buffer, starting at the given file position.

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

public class AsyncFileWrite {
  public static void main(String[] args) {
    Path path = Paths.get("F:\\netjs\\test.txt");
    // increase the buffer size if required
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    // Write Data to buffer
    buffer.put("This will be written to a file.".getBytes());
    buffer.flip();
    try(AsynchronousFileChannel asyncChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE)){
      // Write to async channel from buffer
      // starting from position 0
      Future<Integer> future =  asyncChannel.write(buffer, 0);
      while(!future.isDone()) {
        System.out.println("Waiting for async write operation... ");
        // You can do other processing
      }            
      buffer.clear();            
      System.out.println("Total bytes written- " + future.get());
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } 
  }
}

2. In this Java program for writing file asynchronously we’ll use the write() method where CompletionHandler instance is passed as an argument.

CompletionHandler interface defines two callback methods which you need to implement.

  • completed(V result, A attachment)- Invoked when an operation has completed.
  • failed(Throwable exc, A attachment)- Invoked when an operation fails.
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.nio.channels.CompletionHandler;

public class AsyncFileWrite {
  public static void main(String[] args) throws IOException {
    Path path = Paths.get("F:\\netjs\\test.txt");
    if(!Files.exists(path)){
      Files.createFile(path);
    }
    // increase the buffer size if required
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    // Write Data to buffer
    buffer.put("This will be written to a file.".getBytes());
    buffer.flip();
    try(AsynchronousFileChannel asyncChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE)){
      // Write to channel from buffer, start from position 0
      asyncChannel.write(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
        @Override
        public void completed(Integer result, ByteBuffer attachment) {
          System.out.println("Total bytes written- " + result);
        }

        @Override
        public void failed(Throwable ex, ByteBuffer attachment) {
          System.out.println("Write operation failed- " + ex.getMessage());                    
        }
      });            
    }
  }
}

That's all for this topic Writing a File Asynchronously Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Write to a File in Java
  2. How to Append to a File in Java
  3. How to Write Excel File in Java Using Apache POI
  4. Creating Temporary File in Java
  5. Reading File in Java Using BufferedReader

You may also like-

  1. How to Create Password Protected Zip File in Java
  2. Creating PDF in Java Using Apache PDFBox
  3. Arrange Non-Negative Integers to Form Largest Number - Java Program
  4. Invoking Getters And Setters Using Reflection - Java Program
  5. HashMap in Java With Examples
  6. Interface in Java
  7. Passing Arguments to getBean() Method in Spring
  8. YARN in Hadoop

Tuesday, July 28, 2020

Read File Asynchronously Java Program

In this post we’ll see how to read file asynchronously in Java using java.nio.channels.AsynchronousFileChannel class added in Java 7. Using AsynchronousFileChannel class you can create an asynchronous channel for reading, writing, and manipulating a file.

Opening an Asynchronous channel

Whether you are reading or writing a file asynchronously first thing you need to do is to create an asynchronous channel. For that you can use static open() method of the AsynchronousFileChannel class which opens or creates a file for reading or writing, returning an asynchronous file channel to access the file.

Following code snippet shows how you can create an asynchronous file channel for reading a file.

Path path = Paths.get("F:\\netjs\\test.txt");
AsynchronousFileChannel asyncFileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ)

Reading file asynchronously using AsynchronousFileChannel class

For reading a file asynchronously there are two versions of read() method in the AsynchronousFileChannel class.

  1. read() method that returns a Future.
  2. read() method where you can pass CompletionHandler instance as an argument.

We’ll see examples of of both of these ways to have a better idea.

Reading file asynchronously in Java

1. In the first Java program we’ll use the read method that returns a Future.

abstract Future<Integer> read(ByteBuffer dst, long position)- This method reads sequence of bytes from the opened channel into the buffer passed as argument. Reading starts at the passed file position.

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.Future;

public class AsyncFileRead {
  public static void main(String[] args) {
    Path path = Paths.get("F:\\netjs\\test.txt");
    // buffer into which data is read
    // increase the buffer size if required
    ByteBuffer buffer = ByteBuffer.allocate(4096);
    try(AsynchronousFileChannel asyncChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ)){
      Future<Integer> result = asyncChannel.read(buffer, 0);
      while(!result.isDone()) {
        System.out.println("Waiting for read... ");
        // You can do other processing
      }
      /* File data ready */
      //limit is set to the current position 
      //and position is set to zero
      buffer.flip();
      String data = new String(buffer.array()).trim();
      System.out.println(data);
      buffer.clear();            
    } catch (IOException e) {
      System.out.println("Error while reading file- " + e.getMessage());
      e.printStackTrace();
    }        
  }
}

2. In this Java program for reading file asynchronously we’ll use the read() method where CompletionHandler instance is passed as an argument.

CompletionHandler interface defines two callback methods which you need to implement.

  • completed(V result, A attachment)- Invoked when an operation has completed.
  • failed(Throwable exc, A attachment)- Invoked when an operation fails.
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.nio.channels.CompletionHandler;

public class AsyncFileRead {
  public static void main(String[] args) {
    Path path = Paths.get("F:\\netjs\\test.txt");
    // buffer into which data is read
    // increase the buffer size if required
    ByteBuffer buffer = ByteBuffer.allocate(4096);
    try(AsynchronousFileChannel asyncChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ)){
      asyncChannel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
        // callback methods
        @Override
        public void completed(Integer result, ByteBuffer attachment) {
          System.out.println("Number of bytes read- " + result);
          attachment.flip();
          String data = new String(attachment.array()).trim();
          System.out.println("..." + data.length());
          System.out.println(data);
          attachment.clear();
        }

        @Override
        public void failed(Throwable ex, ByteBuffer attachment) {
          System.out.println("Read operation failed- " + ex.getMessage());                
        }            
      });
      System.out.println("Asynchronous operation in progress.. Once over callback method will be called.");
    } catch (IOException e) {
      System.out.println("Error while reading file- " + e.getMessage());
      e.printStackTrace();
    }        
  }
}

That's all for this topic Read File Asynchronously Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Reading File in Java Using Files.lines And Files.newBufferedReader
  2. Reading All Files in a Folder - Java Program
  3. How to Read Properties File in Java
  4. How to Read File From The Last Line in Java
  5. How to Create PDF From XML Using Apache FOP

You may also like-

  1. Write to a File in Java
  2. Setting And Getting Thread Name And Thread ID - Java Program
  3. How to Untar a File - Java Program
  4. Converting Numbers to Words - Java Program
  5. Nested Class And Inner Class in Java
  6. Generic Class, Interface And Generic Method in Java
  7. Angular Two-Way Data Binding With Examples
  8. Magic Methods in Python With Examples

Thursday, July 23, 2020

What is In-place Algorithm

An in-place algorithm is an algorithm that doesn’t use any auxiliary space to transform the input. Though theoretically that would mean if you have an array of length n then you should use that n space itself to transform the input array but in reality you will definitely use some variables and index for array and that kind of auxiliary space is allowed for an in-place algorithm.

Examples of in-place algorithm are sorting algorithms like Bubble sort, Selection Sort, Insertion Sort which doesn’t require any extra space to perform sorting. That is why space complexity for these algorithms is O(1).

Merge sort, Bucket sort are examples of not in-place or out-of-place sorting algorithms.

In-place algorithm example

Let’s try to understand this auxiliary space requirement of in-place algorithm by taking an algorithm to reverse an array by using separate input and output arrays making it not in-place algorithm.

import java.util.Arrays;

public class ReverseArray {
  public static void main(String[] args) {
    int[] intArr = {47, 85, 47, 34, 7, 10, 0, 106, 2, 54};
    reverseArray(intArr);
  }
    
  static void reverseArray(int[] intArray) {
    int n = intArray.length;
    // Using another array
    int[] tempArray = new int[n];
    for (int i = 0; i < n; i++) { 
      tempArray[n - i - 1] = intArray[i]; 
    } 
    System.out.println("Reversed Array- " + Arrays.toString(tempArray));
  }
}

But the algorithm to reverse an array can very well be written to use the same input array to reverse it. There is no need to use a separate array making it an in-place algorithm.

public class ReverseArray {
  public static void main(String[] args) {
    int[] intArr = {47, 85, 47, 34, 7, 10, 0, 106, 2, 54};
    reverseArray(intArr);
  }
    
  static void reverseArray(int[] intArray) {
    int n = intArray.length;
    for (int i = 0; i < n / 2; i++) {
      int temp = intArray[i];
      intArray[i] = intArray[n - 1 - i];
      intArray[n - 1 - i] = temp;
    }
    System.out.println("Reversed Array- " + Arrays.toString(intArray));
  }
}

That's all for this topic What is In-place Algorithm. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Shell Sort Program in Java
  2. Tree Sort in Java Using Binary Search Tree
  3. Linear Search (Sequential Search) Java Program
  4. Reverse Each Word in a String Java Program
  5. How to Remove Elements From an Array Java Program

You may also like-

  1. Converting String to Enum Type in Java
  2. How to Read File From The Last Line in Java
  3. Java Program to Get Current Date and Time
  4. Running Dos/Windows Commands From Java Program
  5. How to Loop Through a Map in Java
  6. Difference Between Abstract Class And Interface in Java
  7. Angular One-Way Data Binding Using String Interpolation
  8. Changing String Case in Python

Tuesday, July 21, 2020

Pre-defined Functional Interfaces in Java

We saw in the post Functional Interfaces in Java how you can create your own functional interface and also annotate it using @FunctionalInterface Annotation. Though it is not always required that you have to create your own functional interface for each scenario, Java has introduced a new package java.util.function that defines many general purpose pre-defined functional interfaces used by many Java libraries like Collection framework, Java Stream API and used by user code as well. In this post we’ll go through these built-in functional interfaces in Java so you have a good idea which functional interface to use in which context while using with Lambda expressions in Java.


Pre-defined functional interfaces categorization

Functional interfaces defined in java.util.function package can be categorized into five types-

  1. Consumer- Consumes the passed argument and no value is returned.
  2. Supplier- Takes no argument and supplies a result.
  3. Function- Takes argument and returns a result.
  4. Predicate- Takes argument and returns a boolean result (true or false).
  5. Operators- Functional interfaces categorized under Operator are specialized Function where the passed argument and result are of the same type.

Consumer functional interface

Consumer<T> represents a function that accepts a single input argument and returns no result. Consumer functional interface definition is as given below consisting of an abstract method accept() and a default method andThen()-

@FunctionalInterface
public interface Consumer<T> {
  void accept(T t);
  default Consumer<T> andThen(Consumer<? super T> after) {
    Objects.requireNonNull(after);
    return (T t) -> { accept(t); after.accept(t); };
  }
}

Following pre-defined Consumer functional interfaces are categorized as Consumer as all of these interfaces have the same behavior of consuming the passed value(s) and returning no result. You can use any of these based on number of arguments or data type.

  • BiConsumer<T,U>- Represents an operation that accepts two input arguments and returns no result.
  • DoubleConsumer- Represents an operation that accepts a single double-valued argument and returns no result.
  • IntConsumer- Represents an operation that accepts a single int-valued argument and returns no result.
  • LongConsumer- Represents an operation that accepts a single long-valued argument and returns no result.
  • ObjDoubleConsumer<T>- Represents an operation that accepts an object-valued and a double-valued argument, and returns no result.
  • ObjIntConsumer<T>- Represents an operation that accepts an object-valued and a int-valued argument, and returns no result.
  • ObjLongConsumer<T>- Represents an operation that accepts an object-valued and a long-valued argument, and returns no result.

Consumer functional interface Java example

In the example elements of List are displayed by using an implementation of Consumer functional interface.

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class ConsumerExample {
  public static void main(String[] args) {
    Consumer<String> consumer = s -> System.out.println(s);
    List<String> alphaList = Arrays.asList("A", "B", "C", "D");
    for(String str : alphaList) {
      // functional interface accept() method called
      consumer.accept(str);
    }
  }
}

Output

A
B
C
D

Supplier functional interface

Supplier<T> represents a function that doesn't take argument and supplies a result. Supplier functional interface definition is as given below consisting of an abstract method get()-

@FunctionalInterface
public interface Supplier<T> {
  T get();
}

Following pre-defined Supplier functional interfaces are categorized as Supplier as all of these interfaces have the same behavior of supplying a result.

  • BooleanSupplier- Represents a supplier of boolean-valued results.
  • DoubleSupplier- Represents a supplier of double-valued results.
  • IntSupplier- Represents a supplier of int-valued results.
  • LongSupplier- Represents a supplier of long-valued results.

Supplier functional interface Java example

In the example Supplier functional interface is implemented as a lambda expression to supply current date and time.

import java.time.LocalDateTime;
import java.util.function.Supplier;

public class SupplierExample {
  public static void main(String[] args) {
    Supplier<LocalDateTime> currDateTime = () -> LocalDateTime.now();
    System.out.println(currDateTime.get());
  }
}

Function functional interface

Function<T,R> represents a function that accepts one argument and produces a result. Function functional interface definition is as given below consisting of an abstract method apply(), two default methods compose(), andThen() and a static method identity().

@FunctionalInterface
public interface Function<T, R> {

  R apply(T t);

  default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
    Objects.requireNonNull(before);
    return (V v) -> apply(before.apply(v));
  }

  default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
    Objects.requireNonNull(after);
    return (T t) -> after.apply(apply(t));
  }
  static <T> Function<T, T> identity() {
    return t -> t;
  }
}

Following pre-defined Function functional interfaces are categorized as Function as all of these interfaces have the same behavior of accepting argument(s) and producing a result.

  • BiFunction<T,U,R>- Represents a function that accepts two arguments and produces a result.
  • DoubleFunction<R>- Represents a function that accepts a double-valued argument and produces a result.
  • DoubleToIntFunction- Represents a function that accepts a double-valued argument and produces an int-valued result.
  • DoubleToLongFunction- Represents a function that accepts a double-valued argument and produces a long-valued result.
  • IntFunction<R>- Represents a function that accepts an int-valued argument and produces a result.
  • IntToDoubleFunction- Represents a function that accepts an int-valued argument and produces a double-valued result.
  • IntToLongFunction- Represents a function that accepts an int-valued argument and produces a long-valued result.
  • LongFunction<R>- Represents a function that accepts a long-valued argument and produces a result.
  • LongToDoubleFunction- Represents a function that accepts a long-valued argument and produces a double-valued result.
  • LongToIntFunction- Represents a function that accepts a long-valued argument and produces an int-valued result.
  • ToDoubleBiFunction<T,U>- Represents a function that accepts two arguments and produces a double-valued result.
  • ToDoubleFunction<T>- Represents a function that produces a double-valued result.
  • ToIntBiFunction<T,U>- Represents a function that accepts two arguments and produces an int-valued result.
  • ToIntFunction<T>- Represents a function that produces an int-valued result.
  • ToLongBiFunction<T,U>- Represents a function that accepts two arguments and produces a long-valued result.
  • ToLongFunction<T>- Represents a function that produces a long-valued result.

Function functional interface Java example

In the example a Function interface is implemented to return the length of the passed String.

import java.util.function.Function;

public class FunctionExample {
  public static void main(String[] args) {
    Function<String, Integer> function = (s) -> s.length();
    System.out.println("Length of String- " + function.apply("Interface"));
  }
}

Output

Length of String- 9

Predicate functional interface

Predicate<T> represents a function that accepts one argument and produces a boolean result. Abstract method in the Predicate functional interface is boolean test(T t).

Following pre-defined Predicate functional interfaces are categorized as Predicate as all of these interfaces have the same behavior of accepting argument(s) and producing a boolean result.

  • BiPredicate<T,U>- Represents a predicate (boolean-valued function) of two arguments.
  • DoublePredicate- Represents a predicate (boolean-valued function) of one double-valued argument.
  • IntPredicate- Represents a predicate (boolean-valued function) of one int-valued argument.
  • LongPredicate- Represents a predicate (boolean-valued function) of one long-valued argument.

Predicate functional interface Java Example

In the example a number is passed and true is returned if number is even otherwise odd is retuned.

import java.util.function.Predicate;

public class PredicateExample {
  public static void main(String[] args) {
    Predicate<Integer> predicate = (n) -> n%2 == 0;
    boolean val = predicate.test(6);
    System.out.println("Is Even- " + val);    
    System.out.println("Is Even- " + predicate.test(11));
  }
}

Output

Is Even- true
Is Even- false

Operator functional interfaces

Operator functional interfaces are specialized Function interfaces that always return the value of same type as the passed arguments. Operator functional interfaces extend their Function interface counterpart like UnaryOperator extends Function and BinaryOperator extends BiFunction.

Following pre-defined Operator functional interfaces are there that can be used in place of Function interfaces if returned value is same as the type of the passed argument(s).

  • BinaryOperator<T>- Represents an operation upon two operands of the same type, producing a result of the same type as the operands.
  • DoubleBinaryOperator- Represents an operation upon two double-valued operands and producing a double-valued result.
  • DoubleUnaryOperator- Represents an operation on a single double-valued operand that produces a double-valued result.
  • IntBinaryOperator- Represents an operation upon two int-valued operands and producing an int-valued result.
  • IntUnaryOperator- Represents an operation on a single int-valued operand that produces an int-valued result.
  • LongBinaryOperator- Represents an operation upon two long-valued operands and producing a long-valued result.
  • LongUnaryOperator- Represents an operation on a single long-valued operand that produces a long-valued result.
  • UnaryOperator<T>- Represents an operation on a single operand that produces a result of the same type as its operand.

UnaryOperator functional interface Java example

In the example UnaryOperator is implemented to return the square of the passed integer.

import java.util.function.UnaryOperator;

public class UnaryOperatorExample {
  public static void main(String[] args) {
    UnaryOperator<Integer> unaryOperator = (n) -> n*n;
    System.out.println("4 squared is- " + unaryOperator.apply(4));
    System.out.println("7 squared is- " + unaryOperator.apply(7));
  }
}

Output

4 squared is- 16
7 squared is- 49

That's all for this topic Pre-defined Functional Interfaces in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Exception Handling in Java Lambda Expressions
  2. Method Reference in Java
  3. How to Fix The Target Type of This Expression Must be a Functional Interface Error
  4. Java Stream API Tutorial
  5. Java Lambda Expressions Interview Questions And Answers

You may also like-

  1. Java Stream flatMap() Method
  2. Java Lambda Expression Callable Example
  3. Invoke Method at Runtime Using Java Reflection API
  4. LinkedHashMap in Java With Examples
  5. java.lang.ClassCastException - Resolving ClassCastException in Java
  6. Java String Search Using indexOf(), lastIndexOf() And contains() Methods
  7. BeanFactoryAware Interface in Spring Framework
  8. Angular Two-Way Data Binding With Examples

Monday, July 13, 2020

Spring JdbcTemplate Select Query Example

In the post Spring JdbcTemplate Insert, Update And Delete Example I have already discussed how JdbcTemplate can be used for inserting and updating data in the DB. I left behind the part to read from Database using Select query. Purpose for doing that is to discuss in detail the callback part of the JdbcTemplate. This post shows how to use Select query using JdbcTemplate in Spring framework and also talks about the callback methods in detail which shows how you can do resultset to model mapping using RowMapper implementation.

In the post Data access in Spring framework it has been discussed in detail how Spring framework provides templates to manage the fixed part and uses call back to handle the variable part. Fetching data from DB using select query has, as usual, the fixed part like getting connection, cleaning up, handling exception but at the same time Spring framework does need help to map the fetched data to the model. That’s where callback comes into picture.

Technologies used

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

In this Spring JdbcTemplate select query example Apache DBCP is used for providing pooled 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.

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

<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.prog</groupId>
  <artifactId>maven-spring</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>maven-spring</name>
  <url>http://maven.apache.org</url>

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

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    
    <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>
  </dependencies>
</project>

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

Database table for example

For this example I have created a table called employee with the columns id, name and age in the MYSQL DB. Column id is configured as auto increment checked so no need to pass id from your query as DB will provide value for it.

CREATE TABLE `employee` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(35) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

Configuring datasource dependency

First thing is to set up DataSource as a bean. I have used properties file to configure datasource where all the properties are there in the db.properties file.

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

Where as db.properties file which is under the config folder has all the properties.

db.properties

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

Description of the properties is as-

driver class name is the JDBC driver for the DB used. Since MYSQL is used here so the jdbc driver for the same (com.mysql.jdbc.Driver) is provided.

Url – You need to provide url to access your DB server. I have created a schema called netjs and DB is running on the same system so url is jdbc:mysql://localhost:3306/netjs.

Username and password for the DB.

IntialSize is the initial size of the connection pool. It is given as 5 so initially 5 connections will be created and stored in the pool.

To use properties file you need to put following configuration in your XML.

<context:property-placeholder location="classpath:config/db.properties" />

Spring JDBCTemplate configuration

DataSource bean has to be provided as a reference in JdbcTemplate.

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
    <property name="dataSource" ref="dataSource"></property>  
</bean>

Java Classes

Since Spring always promotes to use interfaces and there is also a JEE design pattern for database layer called DAO which also says the same thing - Separate low level data access code from the business layers.

So we have a EmployeeDAO interface with find methods and its implementing class EmployeeDAOImpl. There is also a model class Employee with all the getters/setters.

Employee.java class

public class Employee {
 private int empId;
 private String empName;
 private int age;
 
 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;
 }
}

EmployeeDAO interface

import org.netjs.model.Employee;

public interface EmployeeDAO {
  public List<Employee> findAllEmployees();
  
  public Employee findEmployee(int empId);
}

EmployeeDAOImpl class

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.netjs.dao.EmployeeDAO;
import org.netjs.model.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

@Repository
public class EmployeeDAOImpl implements EmployeeDAO {
  @Autowired
  private JdbcTemplate jdbcTemplate; 
  
  final String SELECT_BY_ID_QUERY = "SELECT id, name, age from EMPLOYEE where id = ?";
  final String SELECT_ALL_QUERY = "SELECT id, name, age from EMPLOYEE";
  
  public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {  
    this.jdbcTemplate = jdbcTemplate;  
  }
    
  public Employee findEmployee(int empId) {
    return this.jdbcTemplate.queryForObject(SELECT_BY_ID_QUERY, new EmployeeMapper(), 
    empId);
  }

  public List<Employee> findAllEmployees() {
    return this.jdbcTemplate.query(SELECT_ALL_QUERY, new EmployeeMapper());
  }

  private static final class EmployeeMapper implements RowMapper<Employee> {
    public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
      Employee emp = new Employee();
      emp.setEmpId(rs.getInt("id"));
      emp.setEmpName(rs.getString("name"));
      emp.setAge(rs.getInt("age"));
      return emp;
    }
  }  
}

Notice how you are not writing any code for getting or closing connection, exception handling. All that fixed part is managed by the JdbcTemplate class. Its the JdbcTemplate which is getting the connection using the DataSource provided to it, creating and executing the statement and closing the connection.

If there is any SQLException thrown that is also caught by JdbcTemplate and translated to one of the DataAccessException and rethrown.

Spring RowMapper

Main thing to demonstrate in this Spring JdbcTemplate select query example is how callback works. Here template callbacks are used to query the DB and then map the returned result set to the model (Employee) object(s).

If you have noticed in findEmployee(int empId) method queryForObject method of JdbcTemplate is used which takes 3 parameters-

  • SQL query String
  • RowMapper object that maps a single result row to a Java object via a RowMapper
  • varargs to bind parameters to the query

Whereas in findAllEmployees() method query method is used which takes only two parameters –

  • SQL query String
  • RowMapper object

as there are no parameters to be passed to the SQL so varargs are not needed in this case.

Main thing here is RowMapper object which in this example is the object of class EmployeeMapper implementing the RowMapper interface.
RowMapper interface has a single method mapRow which takes two arguments -

  1. ResultSet - A table of data representing a database result set
  2. int - the number of the current row
and this method returns the result object for the current row.

For every row in the result set, JdbcTemplate calls the mapRow() method of the RowMapper interface implementing class. Arguments passed are ResultSet and an integer which is the number of the current row in the result set. Using that row number cursor is moved to the given row in the result set.

XML Configuration

<?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:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    
    <context:component-scan base-package="org.netjs.daoimpl" />
    <!--  For reading properties files --> 
    <context:property-placeholder location="classpath:config/db.properties" />
    
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
        <property name="dataSource" ref="dataSource"></property>  
    </bean>  
    <!-- <bean id="employeeDAO" class="org.netjs.daoimpl.EmployeeDAOImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"></property>  
    </bean> -->
    
    <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>

</beans>

If you are not using component scanning, then you can uncomment the bean definition for the EmployeeDAO.

Test class

You can use the following code in order to test the code -

import java.util.List;
import org.netjs.dao.EmployeeDAO;
import org.netjs.model.Employee;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
  public static void main(String[] args) {
    
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
     ("appcontext.xml");
    EmployeeDAO dao = (EmployeeDAO)context.getBean("employeeDAOImpl");  
    
    // Uncomment this to find employee by ID
    /*Employee emp = dao.findEmployee(5);
    System.out.println("Name - "+ emp.getEmpName() + " Age - " + emp.getAge());*/
    
    List<Employee> empList = dao.findAllEmployees();
    System.out.println("Name - "+ empList.get(1).getEmpName() + " Age - " 
      + empList.get(1).getAge());
  }
}

RowMapper implementation as Lambda Expression

RowMapper interface has only single method mapRow which means it is a functional interface. Starting Java 8 it can be implemented as a lambda expression. Since same implementation is used by two methods findEmployee() and findAllEmployees() so it is better to implement it as a lambda block rather than as an inline lambda.

In that case findEmployee() and findAllEmployees() methods will change like this -

public Employee findEmployee(int EmpId) {
  return this.jdbcTemplate.queryForObject(SELECT_BY_ID_QUERY, getMap(), EmpId);
}

public List<Employee> findAllEmployees() {
  return this.jdbcTemplate.query(SELECT_ALL_QUERY, getMap());
}
    
private RowMapper<Employee> getMap(){
  // Lambda block
  RowMapper<Employee> empMap = (rs, rowNum) -> {
      Employee emp = new Employee();
      emp.setEmpId(rs.getInt("id"));
      emp.setEmpName(rs.getString("name"));
      emp.setAge(rs.getInt("age"));
      return emp;
  };
  return empMap;
}

Here it can be seen that lambda block is implemented inside method getMap(). Here lambda is assigned to a functional interface (RowMapper in this case) variable. It has two arguments rs and rowNum, since it is implementing mapRow() method of the RowMapper class so compiler will infer that rs and rowNum are of type ResultSet and int respectively.

That's all for this topic Spring JdbcTemplate Select Query Example. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Configuring DataSource in Spring Framework
  2. Spring NamedParameterJdbcTemplate Insert, Update And Delete Example
  3. Spring NamedParameterJdbcTemplate Select Query Example
  4. How to Inject Prototype Scoped Bean into a Singleton Bean in Spring
  5. Spring Profiles With Examples

You may also like-

  1. Spring Component Scan Example
  2. Excluding Bean From Autowiring in Spring
  3. @Resource Annotation in Spring Autowiring
  4. interface default methods in Java 8
  5. Is String Thread Safe in Java
  6. Difference Between Thread And Process in Java
  7. AtomicInteger in Java With Examples
  8. Java BlockingDeque With Examples

Saturday, July 11, 2020

Data Access in Spring Framework

This Spring data access tutorial provides basics about the DB access through Spring framework like how Spring abstracts the data access, how you can use templates for data access, Spring’s data access exception handling.

If you have to describe how data access is handled by Spring Framework using 2 keywords then those 2 words will be-

  • Abstraction
  • Agnostic

Now JDBC or any ORM framework do provide abstraction of its own and you use JDBC or ORM as an abstract layer to interact with DB then what abstraction does spring provide?

Again two keywords are-

  • Template
  • Exception Handling

Before delving any further into those keywords let’s talk about the “agnostic” feature too (which will cover the Exception handling point too!). It is said that data access exception handling in Spring framework is platform agnostic. What does that mean?

Spring’s data access exception handling is platform agnostic

If you have used JDBC you must be knowing that it forces you to catch SQLException. SQLException is an exception that provides information on a database access error or other errors some of the scenarios when SQLException can be thrown are-

  • The application is not able to connect to the DB.
  • SQL Query which has to be executed is not correct syntactically.

But the question here is by catching SQLException you can’t do much anyway. Also the SQLException hierarchy is not very rich. Though it does provide a String describing the error and an integer error code that is specific to each vendor which is helpful in knowing about the error.

Coming to Spring framework it provides data access mechanism for getting data through JDBC, various ORM frameworks like Hibernate, Ibatis. Now think of a situation where Spring provides the layer over the JDBC or any ORM framework but doesn’t provide any mechanism to handle exceptions thrown by them. In that case your code will become a hotchpotch of Spring templates and then exception handling by JDBC, Hibernate, Ibatis or any other way of data access. That’s where Spring’s platform agnostic exception handling comes to the rescue.

For JDBC org.springframework.jdbc.support package provides SQLException translation functionality and some utility classes. Exceptions thrown during JDBC processing are translated to exceptions defined in the org.springframework.dao package. This means that code using the Spring JDBC abstraction layer does not need to implement JDBC or RDBMS-specific error handling.

All translated exceptions are unchecked exceptions, which gives you the option of catching the exceptions from which you can recover while allowing other exceptions to be propagated to the caller.

Same way implementations of PersistenceExceptionTranslator interface in Spring provides exception translation for data access technologies that throw runtime exceptions, such as JPA, TopLink, JDO and Hibernate.

Using these translator classes Spring translates the platform specific exception to the Spring specific exception under the hood, so you are abstracted from how it is done.

Some of the advantages of the exception handling mechanism followed by Spring are-

  1. Non-intrusive– Since data access exceptions thrown by Spring are not checked exceptions so user is not forced to handle it or declare it. That way you are not making your application tightly coupled with the Spring APIs.
  2. Catch Late- In case of checked exceptions, it is enforced by Java compiler to either catch the exception or declare it in throws clause. So generally developer tends to catch it and do nothing except printing stacktrace or put a logger in order to avoid the compiler error. But that way we are not providing the true information of what exactly happened. It is better to catch exception only when it can be handled appropriately. Since Spring's data access exceptions are unchecked exceptions theses exceptions can be thrown up the call hierarchy, without the botheration of declaring with throws clause or rethrowing them, and the best place in the hierarchy can handle it more effectively.

Spring data access Exception Hierarchy

Spring’s exception hierarchy is quite rich and the main thing is that it can be used with any persistence solution. Whatever persistence solution you are using, if exception is thrown Spring framework will translate it and throw a consistent set of exceptions.

Parent class in Spring's exception hierarchy is DataAccessException and important point about is that it is an unchecked exception. So, you are not forced to catch Spring's data access exceptions, though you can catch them if you want. In fact the convention is that you should not handle any exceptions in the DAO layer, instead throw it to the front-end and handle it.

Some of the sub classes of the DataAccessException class are– BadSqlGrammarException, DuplicateKeyException, EmptyResultDataAccessException, CannotGetJdbcConnectionException, QueryTimeoutException. There are many more if you want to go through the whole list please refer Spring reference doc.

In order to take advantage of Spring’s data-access exceptions, you need to use one of the data access templates provided by Spring framework. That brings us to the point about templates.

Using Templates for Data Access in Spring

Spring provides many templates for data access (For JDBC, for Hibernate, for MongoDB and many more). If you have idea about template design pattern you can get an idea what these templates are doing.

You generally use Template design pattern if you have to design the functionality where some implementation is common among the classes and some implementation differs. So in template design pattern -

  • There is a base class with common implementations.
  • Methods that require individual implementation are mere place holder in base class.
  • Sub classes can provide implementation for those place holder methods.

So, base class provides the template of the implementation and fill what it can (common implementation) and delegates the other parts to the implementing classes.

Same process is used by the Spring data access. Whatever persistence mechanism is used there are some common steps like getting the DB connection, handling exception if thrown and cleaning up the resources (closing the connection) once done. These can be termed as fixed part.

But how and what data is accessed, what data is updated is different for different application. That can be termed as variable part.

Template classes in Spring framework provide implementation for the fixed part and uses a callback approach to handle variable part which is your custom data access code, benefit of template class is that it frees application code from having to do the boilerplate tasks like getting DB connection, handling exceptions, closing connection and results in code that is intention driven. That way the code that is written focuses solely on what the developer wants to do.

As example- JdbcTemplate class is the central class in the JDBC core package. It handles the creation and release of resources, which helps you avoid common errors such as forgetting to close the connection.
It performs the basic tasks of the core JDBC workflow such as statement creation and execution, leaving application code to provide SQL and extract results. The JdbcTemplate class executes SQL queries, update statements and stored procedure calls, performs iteration over ResultSets and extraction of returned parameter values. It also catches JDBC exceptions and translates them to the generic, more informative, exception hierarchy defined in the org.springframework.dao package.

When you use the JdbcTemplate for your code, you only need to implement callback interfaces, giving them a clearly defined contract. The PreparedStatementCreator callback interface creates a prepared statement given a Connection provided by this class, providing SQL and any necessary parameters. The same is true for the CallableStatementCreator interface, which creates callable statements. The RowCallbackHandler interface extracts values from each row of a ResultSet.

Some of the templates provided by Spring framework-

  • jdbc.core.JdbcTemplate– For JDBC connections.
  • jdbc.core.namedparam.NamedParameterJdbcTemplate- For JDBC connections with named parameters.
  • orm.hibernate3.HibernateTemplate– For Hibernate 3.x sessions.
  • orm.hibernate4.HibernateTemplate- For Hibernate 4.x sessions.
  • org.springframework.orm.hibernate5.HibernateTemplate- For Hibernate 5.x sessions.

In order to manage the fixed part like getting connection, releasing resources Spring template needs a reference to a DataSource. Refer Configuring DataSource in Spring Framework to see different ways to configure data source in Spring.

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

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring NamedParameterJdbcTemplate Insert, Update And Delete Example
  2. Spring JdbcTemplate With ResultSetExtractor Example
  3. Spring Batch Processing Using JDBCTemplate batchUpdate() Method
  4. How to Inject Prototype Scoped Bean in Singleton Bean
  5. How to Read Properties File in Spring Framework

You may also like-

  1. Dependency Injection in Spring Framework
  2. Autowiring using XML configuration in Spring
  3. Lazy Initialization in Spring Using lazy-init And @Lazy Annotation
  4. Creating a Maven project in Eclipse
  5. Lambda expressions in Java 8
  6. LinkedHashMap in Java With Examples
  7. Difference Between ReentrantLock and Synchronized in Java
  8. Switch Case Statement in Java With Examples

Friday, July 10, 2020

Spring Batch Processing Using JDBCTemplate batchUpdate() Method

If you have a large number of similar queries it is better to process them in a batch. Processing them as a batch provides better performance as you send a group of queries in a single network communication rather than sending individual queries one by one. Spring JdbcTemplate class supports batch processing using batchUpdate() method.

Spring JdbcTemplate batch processing

For batch processing you can use batchUpdate() method of the Spring JdbcTemplate. As the first parameter of the batchUpdate() you will pass the query that has to be used for batch processing and as second parameter you need to pass the interface BatchPreparedStatementSetter. This interface has two methods which you need to implement.

  • setValues()- This method is used to set the values for the parameters of the prepared statement.
  • getBatchSize()- This method is used to provide the size of the current batch.

Spring JdbcTemplate batch processing using batchUpdate() example

Let’s see an example of inserting rows in a DB table as a batch using Spring JdbcTemplate batch processing.

Technologies used

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

In this batch processing tutorial Apache DBCP is used which provides pooled datasource and MYSQL is used as the back end.

Maven dependencies

If you are using Apache Maven then you can provide dependencies in your pom.xml. Alternatively you can download the jars and add them to the class path.

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

<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</groupId>
  <artifactId>SpringExp</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>SpringExp</name>
  <url>http://maven.apache.org</url>

  <properties>
    <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>
        <!-- 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>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Database table

For this example I have created a table called employee with the columns id, name and age in the MYSQL DB. Column id is configured as auto increment checked so no need to pass id from your query as DB will generate value for it.

CREATE TABLE `employee` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(35) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

DataSource Configuration

DataBase properties are retrieved from a properties file rather than hardcoding in the configuration file. Properties file is stored at the location config/db.properties.

db.properties

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

Java Classes

Java classes needed for Spring batch processing example are as follows-

  1. Employee Bean class (Employee.java)
  2. DAO interface (EmployeeDAO.java)
  3. DAO interface implementation class (EmployeeDAOImpl.java)

Employee.java

public class Employee {
 private int empId;
 private String empName;
 private int age;
 public Employee(String empName, int age){
  this.empName = empName;
  this.age = age;
 }
 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;
 }
}

EmployeeDAO.java

public interface EmployeeDAO {
  public int[] batchInsert(final List<Employee> employees);
}

EmployeeDAOImpl.java

@Repository
public class EmployeeDAOImpl implements EmployeeDAO{
  @Autowired
  private JdbcTemplate jdbcTemplate;

  @Override
  public int[] batchInsert(final List<Employee> employees) {
    final String INSERT_EMP_QUERY = "insert into employee (name, age) values (?, ?)";
    return this.jdbcTemplate.batchUpdate(INSERT_EMP_QUERY,
      new BatchPreparedStatementSetter() {
      
      @Override
      public void setValues(PreparedStatement ps, int i) throws SQLException {
        // emp id is auto generated so not provided
        ps.setString(1, employees.get(i).getEmpName());
        ps.setInt(2, employees.get(i).getAge());        
      }
                    
      @Override
      public int getBatchSize() {
          return employees.size();
      }
    });            
  } 
}
Logic for Spring batch processing is in the bacthInsert() method, where jdbcTemplate.batchUpdate method is called with the query and instance of BatchPreparedStatementSetter. Note that in the class Spring autowiring is used to inject dependencies. Also class is annotated with @Repository annotation so that the class can be automatically discovered using component scanning in Spring.

batchUpdate() method retruns an array of the number of rows affected by each statement.

XML Configuration (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">
    
    <context:component-scan base-package="org.netjs.DAOImpl" />
    <!--  For reading properties files --> 
    <context:property-placeholder location="classpath:config/db.properties" />
    <!-- Data Source configuration --> 
    <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>
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
        <property name="dataSource" ref="dataSource"></property>  
    </bean> 
</beans>

Test class

You can use the following code in order to test the batch insertion of rows in DB table.

public class App {
  public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
             ("appcontext.xml");
    EmployeeDAO empDAO = context.getBean("employeeDAOImpl", EmployeeDAOImpl.class);
    List<Employee> empList = createEmpList();
    int[] rows = empDAO.batchInsert(empList);
    System.out.println("Number of rows inserted- " + rows.length);
  }
    
  private static List<Employee> createEmpList(){
    Employee emp1 = new Employee("Ben", 25);
    Employee emp2 = new Employee("Virat", 29);
    Employee emp3 = new Employee("Joe", 26);
    List<Employee> empList= new ArrayList<Employee>();
    empList.add(emp1);
    empList.add(emp2);
    empList.add(emp3);
    return empList;
  }
}

Output

Aug 06, 2018 12:25:45 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@6fc6f14e: startup date [Mon Aug 06 12:25:44 IST 2018]; root of context hierarchy
Aug 06, 2018 12:25:45 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [appcontext.xml]
Number of rows inserted- 3

Batch operation with multiple batches

You may want to break your batches into several small batches. Though it can be done by making several calls to batchUpdate() method but there is an overloaded variant of batchUpdate() method where you can pass the number of updates to make for each batch and an interface ParameterizedPreparedStatementSetter to set the values for the parameters of the prepared statement. The framework loops over the provided values and breaks the update calls into batches of the size specified.

The batch update methods for this call returns an array of int arrays containing an array entry for each batch with an array of the number of affected rows for each update. The top level array’s length indicates the number of batches executed and the second level array’s length indicates the number of updates in that batch.

Here is an example which shows a batch update using a batch size of 3:

Spring JdbcTemplate batchUpdate example with multiple batches

EmployeeDAO.java

public interface EmployeeDAO {
  public int[][] batchInsert(final List<Employee> employees);
}

EmployeeDAOImpl.java

@Repository
public class EmployeeDAOImpl implements EmployeeDAO{
  @Autowired
  private JdbcTemplate jdbcTemplate;

  @Override
  public int[][] batchInsert(final List<Employee> employees) {
    final String INSERT_EMP_QUERY = "insert into employee (name, age) values (?, ?)";
    return this.jdbcTemplate.batchUpdate(INSERT_EMP_QUERY, employees, 3,
     new ParameterizedPreparedStatementSetter<Employee>() {
      @Override
      public void setValues(PreparedStatement ps, Employee emp) throws SQLException {
          ps.setString(1, emp.getEmpName());
          ps.setInt(2, emp.getAge());                    
      }
    });
  } 
}
XML file is same as above. You can run the Spring batch processing example using the following code.
public class App {
  public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
             ("appcontext.xml");
    EmployeeDAO empDAO = context.getBean("employeeDAOImpl", EmployeeDAOImpl.class);
    List<Employee> empList = createEmpList();
    int[][] rows = empDAO.batchInsert(empList);    
    for(int i = 0; i < rows.length; i++) {        
      System.out.println("Number of rows inserted- " + rows[i].length);    
    }        
  }
    
  private static List<Employee> createEmpList(){
    Employee emp1 = new Employee("Mike", 32);
    Employee emp2 = new Employee("Rahul", 27);
    Employee emp3 = new Employee("Smith", 28);
    Employee emp4 = new Employee("Steve", 45);
    Employee emp5 = new Employee("Rajesh", 21);
    List<Employee> empList= new ArrayList<Employee>();
    empList.add(emp1);
    empList.add(emp2);
    empList.add(emp3);
    empList.add(emp4);
    empList.add(emp5);
    return empList;
  }
}

Output

Aug 07, 2018 10:21:36 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@6fc6f14e: startup date [Tue Aug 07 10:21:36 IST 2018]; root of context hierarchy
Aug 07, 2018 10:21:36 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [appcontext.xml]
Number of rows inserted- 3
Number of rows inserted- 2

That's all for this topic Spring Batch Processing Using JDBCTemplate batchUpdate() Method. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring Batch Processing With List of Objects in batchUpdate() Method
  2. Spring JdbcTemplate With ResultSetExtractor Example
  3. Spring Transaction Management Example - @Transactional Annotation and JDBC
  4. Spring NamedParameterJdbcTemplate Insert, Update And Delete Example
  5. Batch Processing in Java JDBC - Insert, Update Queries as a Batch

You may also like-

  1. Benefits, Disadvantages And Limitations of Autowiring in Spring
  2. Injecting Inner Bean in Spring
  3. Bean Scopes in Spring With Examples
  4. Circular Dependency in Spring Framework
  5. Transient Keyword in Java With Examples
  6. Functional Interfaces in Java
  7. Try-With-Resources in Java With Examples
  8. BigDecimal in Java With Examples