En cada uno de los Daos se abre una conexión distinta, elimine el parámetro y el atributo para comprobar y efectivamente, funciona correctamente. Para que se deja?.
public void guardarProducto(Producto producto) {
Connection con = new ConnectionFactory().recuperaConexion();
try (con) {
final PreparedStatement statement = con.prepareStatement(
"INSERT INTO PRODUCTO " + "(nombre, descripcion, cantidad)" + " VALUES (?, ?, ?)",
Statement.RETURN_GENERATED_KEYS);
try (statement) {
ejecutaRegistro(producto, statement);
}
} catch (SQLException e) {
throw new RuntimeException();
}
}