[RESOLVIDO]Neodatis ODB (atualização de coleções)

Pessoal,

 Recentemente, comecei um projeto utilizando o Neodatis ODB. Apanhei um pouco, mas agora a coisa está indo bem. Contudo, tem um problema que ainda não consegui resolver: quando atualizo os meus objetos, os atributos que sejam collections não são atualizados. Por exemplo:
Perfil perfil = new Perfil();
perfil.getAcessos().add(new Integer(100));

odb = ODBFactory.open("banco");
odb.store(perfil);
odb.close();

// Até este ponto, perfeito. perfil.getAcessos = {100}

odb = ODBFactory.open("banco");

Perfil perfil = (Perfil)odb.getObjects(Perfil.class).get(0);

perfil.getAcessos().clear();
perfil.getAcessos().add(new Integer(200));

odb.store(perfil);
odb.close();

// perfil.getAcessos() continua com {100}
 Alguém tem alguma idéia? Outra coisa: alguma conhece algum lugar com documentação decente sobre o Neodatis? A documentação existente no site do projeto se limita a explicar o feijão-com-arroz...

Oi pango,

Você conseguiu resolver o seu problema, seu código parece legal!

Olivier,

 Infelizmente, ainda não consegui resolver o problema. Se alguém puder dar uma luz...

Olá Pango,

Talvez seu problema era da versão 1.5.

A nova versão do NeoDatis ODB 1.8 já está disponível. Eu testei seu código e está funcionando normal

Olivier,

 Obrigado pela dica. Vou testar com a nova versão...

Qualquer coisa,

me fale se o problema continua!

Olivier,

Funcionou sim, muito obrigado pela sua ajuda!!!

Olá Pango,

que bom!

Qualquer dúvida a respeito do ODB, pode perguntar, eu sou um dos desenvolvedores do projeto NeoDatisODB.

Estamos a disposição!

Olivier,

Muito bacana saber que você participa do projeto. Prepare-se para ser explorado… :smiley:

Parabéns pelo bom trabalho!

Pango,

Sem problemas… :smiley:

Boa tarde amigos!

Bom, estava até a pouco usando Db4O em alguns projetos meus, mas não to conseguindo extrair uma boa performance dele e também não consigo muita ajuda (problema de todo leigo como eu).

Esta vai direto pra você Oliver! Existe algum fórum específico para ODB?

Já de cara arranco com a seguinte dúvida! Existe como fazer uma pesquisa do tipo

IQuery = new CriteriaQuery(Pessoa.class, Where.equal("nome", "Flávio"));

Só que gostaria que fosse retornado na lista, inclusive pessoas com o nome FLÁVIO, ou FláVIO, algo como um equalsIgnoreCase… sei que existe SimpleNativeQuery e foi assim que implementei minha consulta, mas não seria mais lenta? Ah! E um índice pelo atributo nome da classe Pessoa ajudaria neste caso? Mesmo eu usando SimpleNativeQuery.

Desculpe as muitas indagações. Obrigado

Olá Flávio!

Existe um forum específico para ODB sim : http://sourceforge.net/forum/?group_id=179124

Se vc puder postar sua pergunta lá tb serai legal!

Mas vamos lá:

Já existe uma Feature Request para o que vc quer : http://sourceforge.net/tracker/index.php?func=detail&aid=1833157&group_id=179124&atid=887888. Mas ainda não foi implementado. Mas não vai demorar. Aviso assim que ficar pronto!

Vc pode criar um Index sobre o atributo nome que vai melhor muito a performance sobretudo se a classe Pessoa tem muitos objetos.

Com relação a SimpleNativeQuery, por enquanto, ela não sabe aproveitar os indíces. Então vc tem razão com CriteriaQuery fica mais rápido!

Qualquer dúvida, pergunte !!

Só uma então que tá trancando todo o meu projeto

    public static List<Cliente> list() {
        ODB odb = DbAccess.getDb();
        List<Cliente> list = null;

        try {
            IQuery query = new CriteriaQuery(Cliente.class);
            query.orderByAsc("razaoSocial");
            
            list = (List<Cliente>)odb.getObjects(query);

        } catch (Exception e) {
            e.printStackTrace();
            
        } finally {
            return list;
        }
        
    }

java.lang.ClassCastException: org.neodatis.odb.core.list.InMemoryBTreeCollection cannot be cast to java.util.List

É lançada esta exceção quando tendo fazer o “cast”. Todos os meus DAOs utilizam List e em todo o meu sistema. Como vou ter que proceder? Copiar todos os itens de Objects para uma List?

Obrigado

Flávio,

o problema é que todos os resultados do ODB.getObjects retornam objetos que implementam Collection que é uma interface mais generica que List.

A única solução que vejo é :

Não é muito bom pois irá perder um tempo copiando a lista cada vez. Em Termo de memória, a collection retornada pelo odb.getObjects será pegou pelo garbage collector após a saida do metódo.

Como ficou a performance da query na classe Pessoa? Criou um Index?

Bom, estou modificando meu sistema para usar Collection e quando precisar List, daí sim faço um addAll() passando a Collection, o problema agora é que depois de feita uma consulta à base, quando estou tentando fazer outra (não fecho nunca a conexão com a base) retorna a seguinte exceção:

org.neodatis.odb.ODBRuntimeException: 
ODB Release : 406 - 10-12-2007-15-55-59 - th=AWT-EventQueue-0
254:Thread AWT-EventQueue-0 for base db.odb does not have any associated session, base id=AWT-EventQueue-0db.odb
        at org.neodatis.odb.core.server.SessionManager.getSession(SessionManager.java:57)
        at org.neodatis.odb.core.query.execution.GenericQueryExecutor.getSession(GenericQueryExecutor.java:428)
        at org.neodatis.odb.core.query.execution.GenericQueryExecutor.<init>(GenericQueryExecutor.java:109)
        at org.neodatis.odb.core.query.execution.CriteriaQueryExecutor.<init>(CriteriaQueryExecutor.java:45)
        at org.neodatis.odb.core.query.QueryManager.getQueryExecutor(QueryManager.java:106)
        at org.neodatis.odb.core.io.ObjectReader.getObjectInfos(ObjectReader.java:1889)
        at org.neodatis.odb.core.io.ObjectReader.getObjects(ObjectReader.java:1861)
        at org.neodatis.odb.core.io.LocalStorageEngine.getObjects(LocalStorageEngine.java:1590)
        at org.neodatis.odb.main.ODBAdapter.getObjects(ODBAdapter.java:166)
        at dao.VendedorDAO.list(VendedorDAO.java:45)

Sendo que meu DAO e o método para “abertura” de conexão com a base são:

    public static Collection<Vendedor> list() {
        ODB odb = DbAccess.getDb();
        Collection<Vendedor> list = null;

        try {
            IQuery query = new CriteriaQuery(Vendedor.class);
            query.orderByAsc("nome");
            
            list = (Collection<Vendedor>)odb.getObjects(query);

        } catch (Exception e) {
            e.printStackTrace();
            
        } finally {
            return list;
        }
        
    }
public class DbAccess {

    private static ODB db = null;

    static {
        try {
            db = ODBFactory.open("db.odb");

            String[] fieldNames = {"nome"};
            db.getClassRepresentation(Cidade.class).addUniqueIndexOn("cidade-nome", fieldNames, true);


        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Erro ao iniciar aplicação. Verifique as exceçõss", "Erro", JOptionPane.ERROR_MESSAGE);
            e.printStackTrace();
            System.exit(-1);
        }
    }

    public static ODB getDb() {
        return db;
    }

Onde estou errando?

Obrigado

Parece que está ok, vc tem como mandar seu código para tentar reproduzir aqui?

Tb não é aconselhado deixar a conexão aberta o tempo todo. é Bom abrir, executar o que precisa e fechar o odb num finally.

Olá Flávio,

acho que entendi. A sua aplição é Swing ou roda em multi-thread?

Parace que o banco foi aberto numa thread e a consulta executada em outra.

Me confirme isso por favor

Como faço pra te enviar meu projeto, ele é maior que 512K e não consigo anexar ? É em swing sim só que não é multithread que estou utilizando o ODB, o problema de fechar sessão é quando preciso mostrar uma lista em uma tabela ou em combobox, list, assim, uso os objetos que estão vinculados à base e se precisar alterá-los posso simplesmente chamar um .store(objeto) e pronto. Sempre fiz assim com o Db4O e estava legal.

Obrigado

OK então pode deixar aberto o bd.

Não vai precisar enviar o projeto.

O problema que está acontecendo é devido ao swing pelo jeito. Consegui reproduzir aqui. Apesar de vc não usar multithread, o swing usa. e neste caso a sessão do ODB está associada a thread (e não deveria em modo local).

Já estou colocando uma versão que não usa a thread para identificar a sessão.

Obrigado Oliver! Vou ficar “de butuca” esperando… :wink: