Bom dia a todos. Estou uma classe DAO para um programa que cadastra contas bancárias. Já fiz o ConnectionFactory. O meu problema está acontecendo quando vou inserir algo no banco de dados. Segue ai o meu método comentado para melhor entendimento:
public class ContaDAO {
private Connection conn;
public ContaDAO(Connection conn) { // Construtores
this.conn = conn;
}
public ContaDAO() {
}
public boolean create(ContasModel contas) throws SQLException { // Passo como parâmetro a Arraylist que estão os dados das contas. (Sinto que está errado kkk)
String sql = "insert into conta(codConta, titular, saldo, limite)"
+ "values(?,?,?,?);";
try {
PreparedStatement st = conn.prepareStatement(sql); // Aqui mora o problema
st.setInt(1, contas.getConta());
st.setString(2, contas.getNome());
st.setDouble(3, contas.getSaldo());
st.setDouble(4, contas.getLimite());
st.execute();
return true;
} catch (SQLException ex) {
ex.printStackTrace();
return false;
}
}
Ali no início do try ele acusa um NullPointerException, e não consigo resolver de jeito nenhum. Já tentei pegar metodos de outras pessoas, está igual ao meu, mas no meu ocorre isso. O que será que pode ser isso? Sei que essa exception indica que estou tentando acessar algo que ainda não foi inicializado. Mas como resolver essa exception?
public void recebeDados(int conta, String nome, double saldo, double limite) { // Método na controladora que recebe os dados da View
ContasModel modelo = new ContasModel();
ContaDAO DAO = new ContaDAO(); // quando criei aqui e não mandei nada, ele falou para criar um construtor sem parâmetros.
modelo.setConta(conta);
modelo.setNome(nome);
modelo.setSaldo(saldo);
modelo.setLimite(limite);
contas.add(modelo); // Salvando na ArrayList
try {
DAO.create(contas); // Quando chamo o DAO, ele pede pra circundar com try/catch e vem dessa forma pra mim (Não alterei nada nessa parte do código até o momento)
} catch (SQLException ex) {
Logger.getLogger(CadastroContaController.class.getName()).log(Level.SEVERE, null, ex);
}
}
Pode ser que minha instância do DAO ai esteja errada…
E pensando com meus botões, em vez de mandar pro DAO a minha ArrayList, referenciando a classe Model eh melhor, ja que ela vai ser invocada toda vez que uma nova conta for inserida… Dai não preciso dessa iteração que eu fiz…
Ficando dessa forma:
public boolean create(ContasModel contas) throws SQLException { // passando a classe modelo agora, visto que vai ser chamada toda vez que o método na controladora for invocado, não tendo necessidade do iterator que estava antes.
String sql = "insert into conta(codConta, titular, saldo, limite)"
+ "values(?,?,?,?);";
try {
PreparedStatement st = conn.prepareStatement(sql);
st.setInt(1, contas.getConta());
st.setString(2, contas.getNome());
st.setDouble(3, contas.getSaldo());
st.setDouble(4, contas.getLimite());
st.execute();
return true;
} catch (SQLException ex) {
ex.printStackTrace();
return false;
}
}
O Java não manda nada, o compílador só dá sugestões baseado nos códigos que você escreve.
Você não tinha um construtor sem parâmetros, mas escreveu um código chamando um construtor sem parâmetros.
Aí o compilador só te sugeriu criar um pois não existia.
Mas no seu contexto não faz sentido ter um construtor sem parâmetros.
Sua classe ContaDAO só funciona com um objeto do tipo Connection, que é o atributo que você chamou de conn e que é recebido pelo construtor, então não deve existir um construtor sem parâmetros.
Apaga aquele construtor sem parâmetros e trate de passar um objeto Connection para o construtor, conforme ele espera.
ContaDAO dao = new ContaDAO( meuObjetoConnection );
Eu vi uma outra classe DAO aqui de um jeito diferente, sem instanciar algum objeto Connection, mas instanciando meu model. Começa com o usuário preenchendo os dados, e ao pressionar o botão para inserir, é chamado este método no controller:
public class CadastroContaController {
public void recebeDados(int conta, String nome, double saldo, double limite) {
ContasModel modelo = new ContasModel();
// Setando o model
modelo.setConta(conta);
modelo.setNome(nome);
modelo.setSaldo(saldo);
modelo.setLimite(limite);
ContaDAO dao = new ContaDAO(modelo); // Chamando a classe DAO, passando o model como argumento.
dao.create(); // Chamando o método do CRUD que insere no banco de dados.
}
Minha classe de criação de conexão:
public class ConnectionFactory {
private static Connection conexao;
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/banco";
private static final String USER = "root";
private static final String PASS = "sql123";
public static Connection getConnection() {
try {
if (conexao == null) {
Class.forName(DRIVER);
conexao = DriverManager.getConnection(URL, USER, PASS);
}
return conexao;
} catch (ClassNotFoundException ex) {
JOptionPane.showMessageDialog(null, "Erro no driver jdbc!");
ex.printStackTrace();
return null;
} catch (SQLException ex) {
JOptionPane.showMessageDialog(null, "Erro na conexão com o banco de dados!");
ex.printStackTrace();
return null;
}
}
}
E essa daqui eh a classe DAO:
public class ContaDAO {
private ContasModel conta;
private final String SQLINSERIR = "insert into conta values(?,?,?,?);";
ContaDAO(ContasModel conta) { // recebendo o model como parâmetro.
this.conta = conta;
}
public boolean create() {
try {
PreparedStatement ps = Conexão.getConnection().prepareStatement(SQLINSERIR);
ps.setInt(1, conta.getConta());
ps.setString(2, conta.getNome());
ps.setDouble(3, conta.getSaldo());
ps.setDouble(4, conta.getLimite());
ps.executeUpdate();
return true;
} catch (SQLException ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(null, "Não foi possível incluir esta conta no banco de dados.");
return false;
}
}
Porém dentro do PrepareStatement está dando NullPointerException também dessa forma…
Não to conseguindo fazer esse erro parar de acontecer.