problem when updating data from a java table after inserting, No operations allowed after connection closed.?

0

I have a class where I insert data in the db then I update the table but this error appears to me No operations allowed after connection closed. Here I leave the class connection and the class where I insert.

//===============clase conexion==============================
public class Conexion {

    Connection con = null;

    public Conexion() {

        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            System.out.println("Registro exitoso");
            con = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/ropa_trabajo?autoReconnect=true&" +
                            "user=root&password=");
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }


    public Connection getCon() {
        return con;
    }

    public void cerrar() throws SQLException {
        if (con != null) {
            con.close();
        }
    }

}


//===============clase donde inserto==============================
public class trabajador extends Conexion {

    private String rut;
    private String nombre;
    private String apellido_m;
    private String apellido_p;
    private int fono;
    private int nro_calle;
    private String calle;
    private String sector;
    private int calzado;
    private int pantalon;
    private int chaqueta;
    private int id_comuna;
    private int id_estado;
    private int id_usuario;
    private int id_cargo;
    private String password;
    private String opcion;

    public trabajador() {
        super();
    }

    public void insertar() throws SQLException {

        String sql = "INSERT INTO trabajador values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        PreparedStatement sentencia = con.prepareStatement(sql);
        sentencia.setString(1, getRut());
        sentencia.setInt(2, getId_comuna());
        sentencia.setInt(3, 1);
        sentencia.setString(4, getNombre());
        sentencia.setString(5, getApellido_m());
        sentencia.setString(6, getApellido_p());
        sentencia.setInt(7, getFono());
        sentencia.setString(8, getCalle());
        sentencia.setInt(9, getNro_calle());
        sentencia.setString(10, getSector());
        sentencia.setInt(11, getCalzado());
        sentencia.setInt(12, getPantalon());
        sentencia.setInt(13, getChaqueta());
        sentencia.setInt(14, getId_cargo());
        sentencia.setString(15, getPassword());
        sentencia.executeUpdate();
        System.out.println(sentencia);
        //aqui proble usando la variable conexion y el metodo cerrar conexion pero al parecer no cierra la conexion a la base de datos.
        con.close();
    }

}
    
asked by jose miguel jara 08.02.2017 в 22:59
source

2 answers

1

Every time you call insertar at the end of the method you close the connection. If you call the method again, you will inevitably get an error, because you work with a connection already closed.

You should separate the logic of getting a connection and when you close it and the logic that creates the queries. What you have there is a disposable connection.

It is highly recommended to work with a pool of connections. You can use, for example, BasicDataSource apache- commons-dbcp for that.

 BasicDataSource ds = new BasicDataSource();
 ds.setDriverClassName("com.mysql.jdbc.Driver")
 ds.setUsername("jose");
 ds.setPassword("mitremendamentesecretivosecreto");
 ds.setUrl(connectURI);
 ...
 // cuando necesitas una conexión, pides una a la fuente de datos
 Connection conn = ds.getConnection();
 // luego haces lo que necesitas que hacer con la conexión
 // ...
 // finalmente lo devuelves al pool llamando a close()
 // Si, entendiste bien, la conexión que te presta el pool no se cierre con close()
 // se devuelve al pool para ser reusado.
 conn.close();
 // cuando terminaste TODO que quiziste hacer con la BBDD, llamas close() a la fuente de datos
 ds.close();
 // eso cierra todas las conexiones que se habían generado mientras.
    
answered by 08.02.2017 в 23:16
1

Dear @jose miguel jara, what you mention @Stefan Nolde is right, now, at the moment your code makes little sense, because if you implement the method getCon() and cerrar() , so you use the connection directly.

The idea you try to make with the Conexion class is to encapsulate the connection and that they can use only the methods provided for this, then you should make some small changes like the following:

//===============clase conexion==============================
public class Conexion {

    private Connection con = null;

    protected Connection getCon() throws SQLException {

        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (Exception e) {
            throw new SQLException("Driver de BD no disponible en classpath");
        }

        if (con == null || con.isClosed()) {
            con = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/ropa_trabajo?autoReconnect=true&" +
                            "user=root&password=");
            System.out.println("Conexion exitosa");
        }

        return con;
    }

    protected void cerrar() {

        if (con != null) {
            try {
                con.close();
            } catch (Exception ignored) {
                // aqui solo ignoramos, ya que no nos importa si da error al momento de cerrar la conexion
            }
        }
    }

}


//===============clase donde inserto==============================
public class trabajador extends Conexion {

    private String rut;
    private String nombre;
    private String apellido_m;
    private String apellido_p;
    private int fono;
    private int nro_calle;
    private String calle;
    private String sector;
    private int calzado;
    private int pantalon;
    private int chaqueta;
    private int id_comuna;
    private int id_estado;
    private int id_usuario;
    private int id_cargo;
    private String password;
    private String opcion;

    public void insertar() throws SQLException {

        try {
            String sql = "INSERT INTO trabajador values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
            PreparedStatement sentencia = getCon().prepareStatement(sql);
            sentencia.setString(1, getRut());
            sentencia.setInt(2, getId_comuna());
            sentencia.setInt(3, 1);
            sentencia.setString(4, getNombre());
            sentencia.setString(5, getApellido_m());
            sentencia.setString(6, getApellido_p());
            sentencia.setInt(7, getFono());
            sentencia.setString(8, getCalle());
            sentencia.setInt(9, getNro_calle());
            sentencia.setString(10, getSector());
            sentencia.setInt(11, getCalzado());
            sentencia.setInt(12, getPantalon());
            sentencia.setInt(13, getChaqueta());
            sentencia.setInt(14, getId_cargo());
            sentencia.setString(15, getPassword());
            sentencia.executeUpdate();
            System.out.println(sentencia);
        } catch (Exception e) {
            throw new SQLException("Ha ocurrido un error al tratar de ejecutar sentencia", e);
        } finally {
            // siempre se debe cerrar la conexion de o no de error, asi nos aseguramos que nunca queden tomadas las conexiones
            cerrar();
        }
    }

}

Responding to your question about what happens if I do not close connections to the DB, because in a business application this would make the performance of your web container or application server go down, since they handle pools of connections that contain a limited number of connections already established. Regarding the latter, a certain number of open connections are handled, since the opening and closing connections involve in a number of seconds or more extras that will delay your query to the BD through JDBC. A pool of connections drastically helps to lower queries time.

When you close a connection in an environment with a pool of connections, you do not actually close the connection directly, but you delegate the connection to the pool to release it and another resource (another thread) can use it.

I do not really understand how a DB does not close a connection, but I suppose it would also cause performance problems and even deadlocks if they increase infinitely each time you execute a query, although in a standalone application like this one should have problems, because once the main() ends, all the threads of that instance die in the JVM, killing the connections as it passes.

    
answered by 09.02.2017 в 15:17