Search code examples
javaquarkustry-with-resources

It's good to practice using try with resources without finally in Java


I am working with microservices in Quarkus (Java Framework). I have doubts about the closing of connections using try-with-resources. According to the documentation if we have an AutoCloseable object it should close the connection and clean up the objects. Is this really true or is it recommended to continue using finally to close connections?

package com.tmve.subscriber.repository;
import io.agroal.api.AgroalDataSource;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashMap;


public class FindPrepaidSubscriberICCIDRepository {


    public HashMap<String,String> getResources(AgroalDataSource defaultDataSource, String movil){
        HashMap<String,String> map= new HashMap<>();
        try(Connection conn= defaultDataSource.getConnection();
            CallableStatement stm = conn.prepareCall("{call PKG_LCL_CUENTA.B_DATOS_CLIENTE_X_MOVIL(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}"))
        {
            Integer qmovil=Integer.valueOf(movil);
            stm.setInt(1,qmovil);
            stm.registerOutParameter(2, Types.VARCHAR);
            stm.registerOutParameter(3,Types.VARCHAR);
            stm.registerOutParameter(4,Types.VARCHAR);
            stm.registerOutParameter(5,Types.VARCHAR);
            stm.registerOutParameter(6,Types.VARCHAR);
            stm.registerOutParameter(7,Types.VARCHAR);
            stm.registerOutParameter(8,Types.VARCHAR);
            stm.registerOutParameter(9,Types.VARCHAR);
            stm.registerOutParameter(10,Types.VARCHAR);
            stm.registerOutParameter(11,Types.VARCHAR);
            stm.registerOutParameter(12,Types.VARCHAR);
            stm.registerOutParameter(13,Types.VARCHAR);
            stm.registerOutParameter(14,Types.INTEGER);
            stm.registerOutParameter(15,Types.INTEGER);
            stm.registerOutParameter(16,Types.VARCHAR);
            stm.registerOutParameter(17,Types.VARCHAR);
            stm.registerOutParameter(18,Types.INTEGER);
            stm.registerOutParameter(19,Types.VARCHAR);
            stm.registerOutParameter(20,Types.VARCHAR);
            stm.registerOutParameter(21,Types.VARCHAR);
            stm.registerOutParameter(22,Types.VARCHAR);
            stm.registerOutParameter(23,Types.VARCHAR);
            stm.registerOutParameter(24,Types.VARCHAR);
            stm.registerOutParameter(25,Types.INTEGER);
            stm.registerOutParameter(26,Types.INTEGER);
            stm.registerOutParameter(27,Types.VARCHAR);
            stm.registerOutParameter(28,Types.VARCHAR);
            stm.registerOutParameter(29,Types.VARCHAR);

            stm.execute();

            map.put("P_CICCID",stm.getString(27));
            return map;

        } catch (SQLException e) {
            map.put("error_message",e.getMessage());
            return map;
        }
    }

}

Solution

  • Unless the AutoCloseable object you're working with has bugs with its close() method (which would prevent you from using finally anyway), using try-with-resources is preferred over finally.

    The objective reason is in the documentation.

    An object that may hold resources (such as file or socket handles) until it is closed. The close() method of an AutoCloseable object is called automatically when exiting a try-with-resources block for which the object has been declared in the resource specification header. This construction ensures prompt release, avoiding resource exhaustion exceptions and errors that may otherwise occur.

    With a finally block, you have to remember to keep track of what it is you opened and then be sure it's closed at the end of execution. With a try-with-resources block, you're guaranteed that this will happen at the end.