style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

Guardando en Tabla maestra y tabla intermedia con un solo metodo

       
  public void save(Venta v) throws Exception {
                    Connection conn = null;
                    PreparedStatement pstmt = null;
                    PreparedStatement pstmt2 = null;
                    try {
                      conn = new ConnBD().getConnection();
//Guarda tabla maestra
                      String query = "INSERT INTO ventas(id,fecha,peso,precio,tipo,variedad,total)VALUES(?, ?,?,?,?,?,?)";
                      pstmt = (PreparedStatement) conn.prepareStatement(query);
                      pstmt.setInt(1, v.getId());
                      pstmt.setDate(2, getFecha());
                      pstmt.setBigDecimal(3, v.getPeso());
                      pstmt.setBigDecimal(4, v.getPrecio());
                      pstmt.setString(5, v.getTipo());
                      pstmt.setString(6, v.getVariedad());
                      pstmt.setBigDecimal(7, v.getTotal());
                      pstmt.executeUpdate();
                    //Aqui empieza a guardar en tabla intermedia(Guarda varios registros
  for(Tercero t : v.getTercero()){
                         
                          String query2="INSERT INTO terceros_ventas(tercero_id,venta_id)VALUES(?,?)";
                          pstmt2 = (PreparedStatement) conn.prepareStatement(query2);
                          pstmt2.setInt(1, t.getId());
                          pstmt2.setInt(2, v.getId());
                          pstmt2.executeUpdate();
                      }    
                    } finally {
                      pstmt.close();
                      pstmt2.close();
                      conn.close();
                    }
                  }

Esto es correcto de esta manera? si me funciona solo que mi duda es, Esto es una buena practica?

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

Sácalo del ciclo

Saca el PreparedStatement pstmt2 del ciclo. La idea de los PreparedStatements es que se puedan reutilizar, y en cambio estás creando un PreparedStatement en cada iteración y solamente lo usas una vez. Es mejor si lo creas una vez fuera del ciclo, y en cada iteración solamente le pones los nuevos datos y lo ejecutas.

El método debería declarar que arroja SQLException, no Exception (eso es demasiado general, evita ese tipo de declaraciones). Incluso si arroja varios tipos de excepciones distintas, es mejor que las declares a que simplemente pongas Exception.

Te falta validar en el finally que existan esas variables que estás cerrando, porque si por ejemplo se arroja excepción al crear la conexión, los statements serán null y se arrojará una excepción en la primera línea del finally. Valida que exista cada uno (3 ifs, comparando cada variable con null).

Y pues ya fuera del método supongo que manejarás una transacción para que se inserte todo o nada, eso ya depende de la lógica de tu aplicación.

try

Ademas de lo que dijo ezamudio ahi van unos codementarios

try {
    connection.setAutocommit( false ) // inicia la transacción
    pstmt.blahblablah()
    pstmt.executeUpdate()  //ejecuta el primer update
    otroPstmt = connection.prepareStatement("insert into otro blabaabl")  
    for ( ítem : lista ) {
        otroPstmt.blahblah()
        otroPstmt.addBatch()   // agrega varios más al batch
    }
    otro.executeBatch()

    connection.commit()

} catch ( SQLException e ) {
 ...
    connection.rollback()
} finally {
    ....
}
....

Por default la conexión tiene autocommit igual a true, si esto pasa y se inserta la el primer registro y alguno de los demás fallan tu primer registro ya está en la base de datos y no necesariamente es esto lo que quieres.

Al ponerla a false, todo lo que se ejectue formará parte de una sola transacción y es hasta que se invoque el método commit cuando se irá todo a la base de datos.

Gracias

Gracias @ezamudio y @OscarRyz

Al reutilizar el prepared

Al reutilizar el prepared statement utiliza

while(rs.next){
         pstmnt.clearParameters()
         pstmnt.setInt(1, 10);
         ....
}

Esto libera memoria, sobre todo si usas parametros del tipo Object (Timestamp, Date, etc.), si usas primitivos no hay mucha diferencia pero para mi es una buena practica.

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">