Java - Variable Miembro pierde valor

 
Vista:

Variable Miembro pierde valor

Publicado por david (4 intervenciones) el 17/08/2007 12:28:03
Hola, buenas! Estoy empezando en el mundo de la programación Java y hay cosas que se em escapan, a ver si hay alguien que me pueda hechar una mano.

Mi duda es la siguiente:

El IDE es NetBeans 5.0.

He creado una aplicación con dos paquetes.

El primer paquete (CapaDatos) se encarga de todo lo referente a la gestión de datos (conexión a base de datos, y ejecutar sentencias DML sobre la base de datos Mysql). Tiene dos clases. Su código es el siguiente:

/*
* ConexionBDD.java -- Se encarga de crear la conexion a la base de datos MySQL
*/

package CapaDatos;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/* ResultadoProcesoDML solo define unas constantes*/

class ConexionBDD implements ResultadoProcesoDML
{

private Connection conn=null;
private String host=null;
private String db=null;
private String user=null;
private String password=null;

ConexionBDD(String host, String db, String user, String password)
{
this.host=host;
this.db=db;
this.user=user;
this.password=password;

CrearConexion();

}

private void CrearConexion()
{

try
{
Class.forName("com.mysql.jdbc.Driver").newInstance();

conn = DriverManager.getConnection("jdbc:mysql://" + host + "/" + db,user,password);
}
catch (Exception ex)
{
System.out.println(ex.getMessage());
}

}

Connection GetConn()
{
return conn;
}

void LiberarRecursos() throws SQLException
{
conn.close();
conn=null;
}


}

/*
* GestorDatos.java -- Se encarga de realizar las operaciones DML sobre la base de datos
*/

package CapaDatos;

import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.SQLException;
import java.util.ArrayList;


public class GestorDatos implements ResultadoProcesoDML
{

private ConexionBDD conex=null;
private Statement stmt=null;
private ResultSet rs=null;
private int numregs=0;
private int numcols=0;
private ArrayList regs =null;

private final boolean CONSULTA = true;
private final boolean MODIFICA = false;


public GestorDatos(String host, String db, String user, String password) throws SQLException
{
//Conectar a la base de datos
conex=new ConexionBDD(host,db,user,password);
stmt=conex.GetConn().createStatement();
}

public int EjecutarDML(String dml)
{
boolean tipodml=false;
ArrayList reg =null;

try
{
tipodml = stmt.execute(dml);
if (tipodml==CONSULTA)
{
rs = stmt.getResultSet(); //devuelve los registros resultantes de la consulta
numcols=rs.getMetaData().getColumnCount();

regs = new ArrayList();
reg = new ArrayList();
while (rs.next())
{
reg.clear();
for(int i=1;i<=numcols;i++)
{
reg.add(rs.getObject(i)); //rellena el registro actual con los valores de los campos solicitados
}
// Añade el registro actual al conjunto de registros.
regs.add(reg.clone());
}
if (rs != null)
{
rs.close();
reg=null;
}

}
else //se trata de una sentencia de modificación de datos
numregs = stmt.getUpdateCount(); //devuelve el nº de registros afectados

return PROC_CORRECTO;
}
catch (Exception ex)
{
System.out.println(ex.getMessage());
return PROC_NOCORRECTO;
}

}

//Devuelve todos los registros de la última consulta realizada
public ArrayList Getregs()
{
return regs;
}

//Devuelve el nº de registros afectados por la última sentencia de actualización
public int Getnumregs()
{
return numregs;
}

//Devuelve el nº de columnas que tiene la última sentencia de consulta
public int Getnumcols()
{
return numcols;
}

//Esta función realiza el papel de destructor, liberando todos los recursos usados
public void LiberarRecursos() throws SQLException
{
rs=null;
stmt.close();
stmt=null;
conex.LiberarRecursos();

}


}

El segundo paquete(CapaNegocio) se encarga de todo lo referente a la gestión de datos (altas, bajas, consultas en Mysql). Tiene una clase. Su código es el siguiente:

/*
* EntidadNegocio.java -- crea los metodos que se van a usar para la gestion de la base de datos (altas, bajas, modifcaciones, consultas)
*/

package CapaNegocio;

import CapaDatos.*;
import java.sql.SQLException;
import java.util.ArrayList;

public class EntidadNegocio implements ResultadoProcesoDML
{

private GestorDatos gdatos=null;


public EntidadNegocio() throws SQLException
{
GestorDatos gdatos = new GestorDatos();
}


public int Alta(String dml)
{
if (gdatos.EjecutarDML(dml) == PROC_CORRECTO) //solo se hacen altas de un registro
return PROC_CORRECTO;
else
return PROC_NOCORRECTO;
}

public int Baja(String dml)
{
if (gdatos.EjecutarDML(dml) == PROC_CORRECTO)
{
if (gdatos.Getnumregs()==1) //solo se hacen bajas de un registro
return REG_EXISTE;
else
return REG_NOEXISTE;
}
else
return PROC_NOCORRECTO;
}

public int Consulta(String dml) throws SQLException
{

if (gdatos.EjecutarDML(dml) == PROC_CORRECTO)
return PROC_CORRECTO;
else
return PROC_NOCORRECTO;

}

public ArrayList Getdatos() throws SQLException
{
return gdatos.Getregs();

}


public void LiberarRecursos() throws SQLException
{
gdatos.LiberarRecursos();
gdatos=null;
}


}

Por ultimo el metodo main (para las pruebas) lo ha creado NetBeans en el paquete Pruebas, y su codigo es el siguiente:

/*
* Main.java
Clase conductora de la aplicación (PARA PRUEBAS!!!!!!)
*/

package Pruebas;

import CapaNegocio.*;
import java.sql.SQLException;
import java.util.Date;

/**
*
* @author Administrador
*/
public class Main {

/** Creates a new instance of Main */
public Main() {
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
String sql=null;

EntidadNegocio en;
try
{
en = new EntidadNegocio();

sql="SELECT Dni,nombre,apellidos,direccion,fechaalta FROM SOCIO";
if (en.Consulta(sql)==en.PROC_CORRECTO)
{
en.Getdatos();

}
}
catch (SQLException ex)
{
System.out.println(ex.getMessage());
}

}
}

PUES BIEN, AL EJECUTARSE LA LINEA "en = new EntidadNegocio();" DE LA CLASE MAIN, EL OBJETO "EN" HA PERDIDO EL VALOR DE SU VARIABLE MIEMBRO "gdatos".
HE DEPURADO PASO A PASO Y CUANDO ENTRAMOS EN EL CODIGO INTERNO DE LA CLASE A LA QUE PERTENECE "en" TODO SE EJECUTA PERFECTAMENTE Y TIENE SUS VALORES CORRESPONDIENTES, PERO CUANDO SE EJECUTA TODO LOS REFERENTE A ESA LINEA (inicializacion del objeto en) Y VOLVEMOS AL CONTEXTO DE LA CLASE "MAIN" se pierden los valores , Y EN LA LINEA SIGUIENTE "if (en.Consulta(sql)==en.PROC_CORRECTO)"
SE PRODUCE UN "NullPointerException" PORQUE SE HAN PERDIDO LOS VALORES DE LA VARIABLES MIEMBRO DEL OBJETO "en".

Gracias de antemano y un saludo.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:Variable Miembro pierde valor

Publicado por Victor Oliva (66 intervenciones) el 17/08/2007 16:40:58
Hola David,

Revise tu programa. Y el problema que encuentro con esto es lo siguiente:

Debes revisar de la case EntidadNegocio la siguiente parte de tu codigo...

**************************************************************************
private GestorDatos gdatos=null;

public EntidadNegocio() throws SQLException
{
GestorDatos gdatos = new GestorDatos();
}
**************************************************************************

Fijate que tienes un Objeto como variable de "Clase" o "Atributo" y es lo correcto.
Pero en el constructor de la clase EntidadNegocio tienes esta linea "GestorDatos gdatos = new GestorDatos();" fijate que estas creando un nuevo objeto "gdatos", que es una variable de metodo.
Entonces creas un nuevo objeto que muere cuando el metodo termina. Pero nunca tocaste al "private GestorDatos gdatos=null;". Ese siguio como null.
La solucion a esto es lo siguiente:

**************************************************************************
private GestorDatos gdatos=null;

public EntidadNegocio() throws SQLException
{
this.gdatos = new GestorDatos();
}
**************************************************************************

Fiajte que agregue un "this." este es un objeto que hace referencia al mismo objeto en el que estas parado, me entiendes?
Con eso estaras haciendo referencia al objeto que es "Miembro de Clase o atributo de clase".

Lo otro es que no existe ningún constructor GestorDatos(), tienes este constructor GestorDatos(String host, String db, String user, String password).

Acuerdate que existe un contructor "por defecto" con parametros vacios al crear una clase, pero este desaparece al momento que creas un nuevo constructor.

Espero que te sirva y me hayas entendido.

Victor Oliva
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Porque no es la variable miembro

Publicado por Gonzalo (180 intervenciones) el 17/08/2007 17:04:04
Lo que inicializas en el constructor de EntidadNegocio no es el gdatos miembro:

public class EntidadNegocio implements ResultadoProcesoDML {

····private GestorDatos gdatos=null;

····public EntidadNegocio() throws SQLException {
········GestorDatos gdatos = new GestorDatos();
····}

//etc
}

Fíjate bien. Cuando haces:
GestorDatos gdatos = new GestorDatos();
estás declarando una variable local de tipo GestorDatos con el mismo nombre gdatos, e inicializándola. Pero no es la variable miembro de la clase.

Cambia el constructor a:

····public EntidadNegocio() throws SQLException {
········gdatos = new GestorDatos();
····}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Porque no es la variable miembro

Publicado por david (4 intervenciones) el 17/08/2007 19:17:18
muchas gracias!!!!. Me he tirado varios días y no he dado con la tecla!!!

A veces los errores más triviales son los peores!!

Muchas gracias!!!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar