Ir ao conteúdo
  • Cadastre-se

Java Exceção 'Can't call commit when autocommit=true'


Posts recomendados

Olá, tudo bem?

 

Estou seguindo um curso online e em determinado ponto eu travei. Acontece que em determinada linha é lançada uma exceção. O professor explicou sobre ela, inclusive mostrou ela acontecendo, e passou uma solução, mas para mim essa solução não funcionou.

 

O programa consiste em usar a classe CachedRowSet para atualizar um registro do banco de dados. A classe toda funciona, os dados são modificados, mas fica lançando a exceção.

 

Procurei em vários lugares e praticamente se dividem em duas soluções:

  1. Usar a tag 'relaxAutoCommit=true' na URL (solução do professor).
  2. Usar a classe Connection e chamar o método setAutoCommit(false).

 

Não cheguei a testar a segunda solução, queria entender o por que da primeira solução funcionar para todo mundo e para mim não. Desconfio que seja algo com o driver, estou usando o MySQL na versão 8.0.22, enquanto o professor usa a 5. alguma coisa (o curso é antigo). Também não cheguei a testar com outra versão.

 

Segue o código fonte:

Comprador

Spoiler


package bancodados;

/**
 * Classe de modelagem, reflete a estrutura da tabela no banco de dados.
 */
public class Comprador {

    private int id;
    private String nome;
    private String cpf;

    public Comprador() {
    }

    public Comprador(String nome, String cpf) {
        this.nome = nome;
        this.cpf = cpf;
    }

    public Comprador(int id, String nome, String cpf) {
        this.id = id;
        this.nome = nome;
        this.cpf = cpf;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getCpf() {
        return cpf;
    }

    public void setCpf(String cpf) {
        this.cpf = cpf;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Comprador comprador = (Comprador) o;

        return id == comprador.id;
    }

    @Override
    public int hashCode() {
        return id;
    }

    @Override
    public String toString() {
        return "Comprador{" +
                "id=" + id +
                ", nome='" + nome + '\'' +
                ", cpf='" + cpf + '\'' +
                '}';
    }
}

 

ConnectionFactory

Spoiler


package bancodados;

import javax.sql.rowset.CachedRowSet;
import javax.sql.rowset.RowSetProvider;

/**
 * Responsável por abrir e fechar as conexões com o banco de dados.
 */
public class ConnectionFactory {

    public static CachedRowSet getConnection() {
        /*
         * URLs tentadas:
         *
         * jdbc:mysql://127.0.0.1:3306/Agencia
         * jdbc:mysql://127.0.0.1:3306/Agencia?relaxAutoCommit=true
         * jdbc:mysql://127.0.0.1:3306/Agencia?useSSL=false&relaxAutoCommit=true
         *
         * Essa última é a mesma do curso.
         */

        final String url = "jdbc:mysql://127.0.0.1:3306/Agencia?useSSL=false&relaxAutoCommit=true";
        final String user = "";     // Removido por segurança
        final String pass = "";     // Removido por segurança

        try {
            CachedRowSet rowSet = RowSetProvider.newFactory().createCachedRowSet();
            rowSet.setUrl(url);
            rowSet.setUsername(user);
            rowSet.setPassword(pass);
            return rowSet;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void close(AutoCloseable... closeables) {
        if (closeables == null) return;

        for (AutoCloseable closeable : closeables) {
            if (closeable == null) continue;

            try {
                closeable.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

 

CompradorDB

Spoiler


package bancodados;

import javax.sql.rowset.CachedRowSet;
import java.sql.SQLException;

/**
 * É como se fosse um DAO, possui apenas o método que dá problema.
 */
public class CompradorDB {

    public static void atualizar(Comprador comprador) {
        if (comprador == null) return;

        final String sql = "SELECT id, nome, cpf FROM comprador WHERE id = ?";

        CachedRowSet rowSet = ConnectionFactory.getConnection();

        if (rowSet == null) return;

        try {
            rowSet.setCommand(sql);
            rowSet.setInt(1, comprador.getId());

            if (rowSet.next()) {
                rowSet.updateString("nome", comprador.getNome());
                rowSet.updateString("cpf", comprador.getCpf());
                rowSet.updateRow();

                // Essa linha lança a exceção.
                rowSet.acceptChanges();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            ConnectionFactory.close(rowSet);
        }
    }
}

 

Principal

Spoiler


package bancodados;

public class Principal {

    public static void main(String[] args) {
        Comprador comprador = new Comprador(1, "Novo Nome", "123.123.123/12");

        CompradorDB.atualizar(comprador);
    }
}

 

Exceção

Spoiler


java.sql.SQLException: Can't call commit when autocommit=true
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:67)
	at com.mysql.cj.jdbc.ConnectionImpl.commit(ConnectionImpl.java:794)
	at com.sun.rowset.internal.CachedRowSetWriter.commit(CachedRowSetWriter.java:1405)
	at com.sun.rowset.CachedRowSetImpl.acceptChanges(CachedRowSetImpl.java:893)
	at db.CompradorDB.atualizar(CompradorDB.java:35)
	at test.RowSetTest.main(RowSetTest.java:10)
javax.sql.rowset.spi.SyncProviderException: Can't call commit when autocommit=true
	at com.sun.rowset.CachedRowSetImpl.acceptChanges(CachedRowSetImpl.java:912)
	at db.CompradorDB.atualizar(CompradorDB.java:35)
	at test.RowSetTest.main(RowSetTest.java:10)

 

Ignore o número das linhas informadas, essa exceção foi tirada do projeto original (com mais classes).

 

Desde já eu agradeço.

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!