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...
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.
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?
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;
}
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.
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.