1

I am trying to make several read queries in parallel in Oracle database from a Java application. I use CallableTasks to make these queries. The sample of the Callable Task is as follows:

public class MyCallableTask<T> implements Callable<List<T>> {
    
    private String sql;
    private Connection connection;
    private Class<T> classInstance;

    public MyCallableTask(String sql, Connection connection, Class<T> classInstance) {
//      the connection object is sent here from a db connection pool, so that each callable has its own connection instance.
        this.connection = connection;
        this.sql = sql;
        this.classInstance = classInstance;
    }

    @Override
    public List<T> call() throws Exception {
        PreparedStatement ps = connection.createPreparedStatement(sql);
        Resultset rs = ps.executeQuery();
//      Using commons-dbutils resultsethandler to map the resultset to a Java Bean
        ResultSetHandler<List<T>> resultSetHandler = new BeanListHandler<>(classInstance);
        List<T> requiredList = resultSetHandler.handle(rs);
        return requiredList;
    }

}

My sample main class looks as follows:

public class MyMain {

    public static void main() {
        MyConnectionPool myConnectionPool = new MyConnectionPool();
        Connection connection1 = myConnectionPool.getConnection();
        Connection connection2 = myConnectionPool.getConnection();
        String studentSql = "Select X, Y from AB.Students Where Z = 2";
        String teacherSql = "Select P, Q from AB.Teachers Where R = 1";
        ExecutorService executorService = Executors.newFixedThreadPool(6);
        Callable<List<Student>> callableStudents = new MyCallableTask<>(studentSql, connection1, Student.class);
        Callable<List<Teacher>> callableTeachers = new MyCallableTask<>(teacherSql, connection2, Teacher.class);
        Future<List<Student>> studentsFuture = executorService.submit(callableStudents);
        Future<List<Teacher>> teachersFuture = executorService.submit(callableTeachers);
        List<Student> students = studentsFuture.get();
        List<Teacher> teachers = teachersFuture.get();
        System.out.println(students + " " + teachers);
    }

}

The above code works for each sql query on two different threads as expected, but fails on the line in which I call

List<T> requiredList = resultSetHandler.handle(rs);

The exception thrown is a NoSuchElementException. The case is curious to me because when I run the above synchronously it works perfectly fine. Infact even when I insert breakpoints and run in debug mode, it runs perfectly fine and creates two different worker threads as expected. But it always breaks in a normal run.

Please try to answer if possible. Really appreciate any help.

wakarK
  • 36
  • 7

0 Answers0