[RESOLVIDO]Erro na criação da Connection Factory (Unknown initial character set index '255' received from server.)

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?

Ops escrevi código errado no parâmetro kk corrigindo:

public boolean create(ArrayList <ContasModel> contas) throws SQLException {
        for (ContasModel obj : contas){
        String sql = "insert into conta(codConta, titular, saldo, limite)"
                + "values(?,?,?,?);";
        try {
            PreparedStatement st = conn.prepareStatement(sql);
            st.setInt(1, obj.getConta());
            st.setString(2, obj.getNome());
            st.setDouble(3, obj.getSaldo());
            st.setDouble(4, obj.getLimite());
            st.execute();
            return true;    //  ai sim segue o código

Como você inicializou o atributo conn?

Posta o código onde você criou o objeto da classe ContaDAO.

Por que você tem um construtor sem parâmetros?
Não faz sentido já que você tem um construtor que recebe o objeto Connection por parâmetro.

Já vou mostrar o motivo meu caro:

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… :thinking:

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. :slight_smile:

ContaDAO dao = new ContaDAO( meuObjetoConnection );
1 curtida

No caso, o “meuObjetoConnection” seria o que, especificamente? :thinking:

             +-----------------+
             | SERIA ISSO AQUI |
             +--------+--------+
                      |
                      |
                      V
public ContaDAO(Connection conn) { // Construtores
    this.conn = conn;
}

Está seguindo algum material para aprender?

1 curtida

Apenas coisas que vou achando na internet mesmo. Teria alguma sugestão?

Certo, mas ai la na controladora, como eu faria?

Onde você inicializa a conexão com o banco de dados?
Lá com certeza você criou um objeto do tipo Connection.

No caso vc quer dizer a ConnectionFactory?

Lá tem isso aqui:

public static Connection getConnection() {
                try {
                    Class.forName(DRIVER);

                return DriverManager.getConnection(URL, USER, PASS);

            } catch (ClassNotFoundException | SQLException ex) {
                throw new RuntimeException("Erro na conexão!", ex);
            }
        }

Posta o código onde você realiza a conexão com o banco de dados.

Editei o post acima

E onde você chama o método getConnection()?

Bingo! Eu não estou chamando em lugar nenhum :sweat_smile:
Eu chamaria este método dentro do método create? :thinking:

Não sei, não sei quais classes você tem, quais as responsabilidades dela nem como elas se relacionam.

Deixa eu ver se consigo te explicar:

  • Tenho a View, com a interação com o usuário.
  • Controller, que tem o metodo q pus ai acima que insere tanto na arraylist quanto no model.
  • Model, que salva os dados das contas inseridas.
  • ConnectionFactory, que invoca o banco de dados e também tem os métodos que fecham o mesmo
  • ContaDAO que é essa que estamos discutindo.

Então imagino que o Controller é quem tem vai manter a Connection em uma variável de instância e passar ela para o(s) DAO(s) que você criar.

1 curtida

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. :thinking:

Cadê o fonte da classe Conexão?