[RESOLVIDO] Salvando no Db4o

Fala galeraaa, tudo tranquilo? :smiley:

Amigos, tenho um problema que não me entra na cabeça.

Eu estou desenvolvendo um sistema com o bando de dados Db4o.
E eu tenho uma tela de cadastro de usuários, feita com swing.
O problema é o seguinte:

Quanto tento fazer um “store” do objeto, ele diz que o banco de dados está fechado. :frowning:

com.db4o.ext.DatabaseClosedException

O problema é que não consigo entender onde porque ele pega o banco fechado.
O trecho de código que ele tá tentando executar é esse, exatamente na hora de salvar um novo dado.

[code]
if (editando) {
UsuarioDAO dao = new UsuarioDAO();

   UsuarioVO exemplo = new UsuarioVO(Integer.valueOf(editID.getText()));
   UsuarioVO novo = new UsuarioVO();
   novo.setNome(editNome.getText());
   novo.setEmail(editEmail.getText());
   novo.setUsuario(editUsuario.getText());
   novo.setSenha(editSenha.getText());                
            
   dao.update(exemplo, novo);

} else {
UsuarioDAO dao = new UsuarioDAO();
UsuarioVO usuario = new UsuarioVO(dao.getLast() + 1);

   usuario.setNome(editNome.getText());
   usuario.setEmail(editEmail.getText());
   usuario.setUsuario(editUsuario.getText());
   usuario.setSenha(editSenha.getText());
                            
   dao.insert(usuario);

}[/code]

O meu problema está dando no else, desse if aí!
Quando clico em novo, e deixa false o boolean editando, e quando eu clico em editar,
ele deixa true.
Dentro do else, ele tá dando problema na linha 14, desse código aí, específicamente em:

dao.getLast() + 1

O meu DAO está assim:

[code]package br.com.andrey.usuario;

import com.db4o.Db4oEmbedded;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import java.util.ArrayList;
import java.util.List;

/**
*

  • @author Andrey
    */
    public class UsuarioDAO {

    ObjectContainer db = Db4oEmbedded.openFile(
    Db4oEmbedded.newConfiguration(), “C:/Sistema/dados/usuarios.odb”);

    public List getAll() {
    List lista = new ArrayList();
    try {
    ObjectSet resultado = db.queryByExample(UsuarioVO.class);
    for (Object o : resultado) {
    lista.add((UsuarioVO) o);
    }
    } catch (Exception e) {
    System.err.println(e);
    } finally {
    db.close();
    }
    return lista;
    }

    public UsuarioVO getById(int id) {
    UsuarioVO usuario = null;
    try {
    UsuarioVO exemplo = new UsuarioVO(id);
    usuario = (UsuarioVO) db.queryByExample(exemplo).next();
    } catch (Exception e) {
    System.err.println(e);
    } finally {
    db.close();
    }
    return usuario;
    }

    public int getLast() {
    int i = 0;
    int last = 0;

     while (i < getAll().size()) {
         if (last < getAll().get(i).getId()) {
             last = getAll().get(i).getId();
         }
         i++;
     }
     return last;
    

    }

    public void insert(UsuarioVO usuario) {
    try {
    db.store(usuario);
    } catch (Exception e) {
    System.err.println(e);
    } finally {
    db.close();
    }
    }

    public void update(UsuarioVO exemplo, UsuarioVO novo) {
    try {
    UsuarioVO achado = (UsuarioVO) db.queryByExample(exemplo).next();
    achado.setNome(novo.getNome());
    achado.setEmail(novo.getEmail());
    achado.setUsuario(novo.getUsuario());
    achado.setSenha(novo.getSenha());
    db.store(achado);
    } catch (Exception e) {
    System.err.println(e);
    } finally {
    db.close();
    }
    }

    public void delete(UsuarioVO exemplo) {
    try {
    db.delete(exemplo);
    } catch (Exception e) {
    System.err.println(e);
    } finally {
    db.close();
    }
    }

}[/code]

Galera, se puderem me ajudar, agradeço!
Enquanto isso, vou me virando aqui.
Desde já meu obrigado.
:slight_smile:

O que acontece é o seguinte, você criou uma instancia de UsuarioDao dentro do else. Até ai tudo bem.
Quando você fez isso acessou o dao pelo método getLast().
Em getLast() você fez uma chamada ao método getAll() (getLast().seze()).
Dai após a consulta no banco, você fecha a conexão no finally (em getAll()).
De volta ao método getLast(), você tenta acessar novamente o método getAll() (getAll().get(i).getId()), porém não tem mais um objeto db criado, quando fechou ele no finally é como se tivesse setado ele como null.

O que você pode fazer para consertar isto é criar uma lista que receba o retorno do método getAll():

public int getLast() {  
        int i = 0;  
        int last = 0;  
        List&lt;UsuarioVO&gt; lista = getAll();  
        while (i &lt; lista.size()) {  
            if (last &lt; lista.get(i).getId()) {  
                last = lista.get(i).getId();  
            }  
            i++;  
        }  
        return last;  
    }  

Porém lá dentro do else na ultima linha você vai executar: dao.insert(usuario);
Como seu objeto db já foi fechado, por que ele faz parte da mesma instancia dao, vai ter o mesmo erro de conexão fechada.

Para resolver você deve criar um novo dao: dao = new UsuarioDao();
Ou lá na classe UsuarioDao modificar o modo como cria a conexão:

public class DBConexao {
	private static ObjectContainer db;
	
	static {
		db = Db4oEmbedded.openFile(Db4oEmbedded.newConfiguration(), &quot;C:/Sistema/dados/usuarios.odb&quot;);  
	}
	
	public static ObjectContainer getConexao() {
		return db;
	}
}

Na classe UsuarioDao faça:


private ObjectContainer db;


public List&lt;UsuarioVO&gt; getAll() {  
        List&lt;UsuarioVO&gt; lista = new ArrayList&lt;UsuarioVO&gt;();  
		db = DBConexao.getConexao();
        try {  
            ObjectSet resultado = db.queryByExample(UsuarioVO.class);  
            for (Object o : resultado) {  
                lista.add((UsuarioVO) o);  
            }  
        } catch (Exception e) {  
            System.err.println(e);  
        } finally {  
            db.close();  
        }  
        return lista;  
}  
//faça isso em todos os métodos.

Caaaara, legal!
Realmente é uma implementação muito interessante, porém,
ele continua retornando database closed exception.
Eu vou dar uma mexida no código e ver se consigo fazer algo.
Se tiver alguma outra idéia, posta ae!
Falow.

Experimenta assim:

public class DBConexao {	
	public static ObjectContainer getConnection() { {
		return Db4oEmbedded.openFile(Db4oEmbedded.newConfiguration(), "C:/Sistema/dados/usuarios.odb");  
	}
}

[quote=romarcio]Experimenta assim:

public class DBConexao { public static ObjectContainer getConnection() { { return Db4oEmbedded.openFile(Db4oEmbedded.newConfiguration(), "C:/Sistema/dados/usuarios.odb"); } } [/quote]

Aeeee, bacana!
Rodou exatamente do jeito que eu queria.
E melhor: nesse DBConexão, eu implementei o método para receber um string do nome do banco.
Pois vou usar multiplos bancos.
Obrigado Romarcio.
Foi de grande ajuda.
RESOLVIDO!
;D

:thumbup:

Edita o seu 1° post e coloca [RESOLVIDO] ao lado do titulo.