Banco de Dados OO NeoDatis ODB versão 1.8 está disponível

Oi Andre,

o NeoDatis ainda não tem esse mecanismo :frowning:

Mas vale a pena postar uma Feature Request no SourceForge…

Digamos que eu tenha um objeto e esse objeto tem um getOutroObjeto e assim vai e o meu objeto inicial tem outro getObjeto que tem vários outros objetos… ele vai carregar tudo isso de uma vez só?

Por exemplo: tenho um objeto Estado, que tem getCidades, que cada cidade tem getBairros, que cada bairro tem getLogradouros… imagine só

Sim vc tem razão, vai carregar tudo!

Vc pode colocar uma Feature Request no http://sourceforge.net/tracker/?group_id=179124&atid=887888

Valeu Andre

[quote=Olivier]Andre,

por enquanto o NeoDatis ODB não tem versão específica para java 1.5. E ai não tem como usar Generics :-(. Mas está na lista de Feature Request!

[/quote]

Se isso for feito, já estarão a frente do Hibernate.

[quote=Olivier]Sim vc tem razão, vai carregar tudo!

Vc pode colocar uma Feature Request no http://sourceforge.net/tracker/?group_id=179124&atid=887888

Valeu Andre

[/quote]

Vou postar sim. Por padrão, acho eu, no Hibernate o OneToMany já vem com lazy=true, ou seja não carrega os objetos de um objeto já de cara. Não sei se tem como fazer isso da forma como o NeoDatis foi implementado, mas na minha opinião é algo que pode melhorar muito o desempenho do banco. Principalmente no exemplo que citei.

[quote=Olivier]Sim vc tem razão, vai carregar tudo!

Vc pode colocar uma Feature Request no http://sourceforge.net/tracker/?group_id=179124&atid=887888

Valeu Andre

[/quote]

Acha que ele demora muito pra carregar todos os objetos que te falei? O Hibernate vai fazer um select de banco o NeoDatis carrega os objetos diretamente, certo?

[quote=andre_guitar7][quote=Olivier]Sim vc tem razão, vai carregar tudo!

Vc pode colocar uma Feature Request no http://sourceforge.net/tracker/?group_id=179124&atid=887888

Valeu Andre

[/quote]

Vou postar sim. Por padrão, acho eu, no Hibernate o OneToMany já vem com lazy=true, ou seja não carrega os objetos de um objeto já de cara. Não sei se tem como fazer isso da forma como o NeoDatis foi implementado, mas na minha opinião é algo que pode melhorar muito o desempenho do banco. Principalmente no exemplo que citei.[/quote]

Com certeza deve melhorar. Na versão 1.5 tinhamos feito uma coisa parecida usando ASM mas tiramos pois estava aumentando bastante o tamanho do jar. Mas vamos analisar de novo. O único problema disso é que em vez de retornar uma instância da sua classe, retornaremos uma instância de uma classe criada em runtime (usando ASM) que herda da sua classe em quais os métodos get que retornam objetos não nativos farão o load on demand. Neste caso, se alguem compara a classe usando == não funcionará. Mas Hibernate faz a mesma coisa, ele retorna uma subclasse da sua com o nome NomeClasse_enhancedByCGlib usando CGLib, então não deve ser tão problemático.

[quote=andre_guitar7][quote=Olivier]Sim vc tem razão, vai carregar tudo!

Vc pode colocar uma Feature Request no http://sourceforge.net/tracker/?group_id=179124&atid=887888

Valeu Andre

[/quote]

Acha que ele demora muito pra carregar todos os objetos que te falei? O Hibernate vai fazer um select de banco o NeoDatis carrega os objetos diretamente, certo?[/quote]

Andre, não sei se entendi bem a pergunta…

Olivier, sou iniciante no uso desses bancos, estou até pesquisando o Neodatis. Por exemplo, no db4o, tive problemas com SODA queries e Enums (Ver. 6.4), então tive que partir para Native Queries, para realizar uma consulta de OSs, não encerradas, de determinado período, ordenadas por data:[code] public void listaBasDeHoje() {
ba_lista = ba_dao.getSession().query(new Predicate<BA>() {
private static final long serialVersionUID = 1L;

		public boolean match(BA ba) {
			return (ba.getStatus() != BA_Status.Finalizado
					&& ba.getData_promessa().after(data_inicial) && ba
					.getData_promessa().before(data_final));
		}
	}, new Comparator&lt;BA&gt;() {
		public int compare(BA ba1, BA ba2) {
			return ba1.getData_promessa().compareTo(
					ba2.getData_promessa());
		}

	});
}

[/code] Fiquei pensando se tivesse de fazer agrupamentos ou algo do gênero, como ficaria. Poderia dar alguma dica ou exemplo com o Neodatis. A propósito, o Neodatis tem integridade referencial?

Grato,

Genildof,

O NeoDatis não suporta group by de maneira nativa. Mas o NeoDatis tem um recurso que permite tratar isso : Os triggers. Vc pode criar um trigger afterSelect que será chamado para cada objeto onde vc poderá fazer o que for preciso como agrupar ou somar seus dados.

Dê uma olhada no thread http://www.guj.com.br/posts/list/76970.java na última resposta (minha) da primeira página onde eu mostro como fazer um sum.

Me fale se ajuda, ok?

Com relação aos enum, não sei, eu vou testar.

Esqueci: NeoDatis ainda não suporta Integridade referencial. Mas está no RoadMap.

[quote=Olivier][quote=andre_guitar7][quote=Olivier]Sim vc tem razão, vai carregar tudo!

Vc pode colocar uma Feature Request no http://sourceforge.net/tracker/?group_id=179124&atid=887888

Valeu Andre

[/quote]

Vou postar sim. Por padrão, acho eu, no Hibernate o OneToMany já vem com lazy=true, ou seja não carrega os objetos de um objeto já de cara. Não sei se tem como fazer isso da forma como o NeoDatis foi implementado, mas na minha opinião é algo que pode melhorar muito o desempenho do banco. Principalmente no exemplo que citei.[/quote]

Com certeza deve melhorar. Na versão 1.5 tinhamos feito uma coisa parecida usando ASM mas tiramos pois estava aumentando bastante o tamanho do jar. Mas vamos analisar de novo. O único problema disso é que em vez de retornar uma instância da sua classe, retornaremos uma instância de uma classe criada em runtime (usando ASM) que herda da sua classe em quais os métodos get que retornam objetos não nativos farão o load on demand. Neste caso, se alguem compara a classe usando == não funcionará. Mas Hibernate faz a mesma coisa, ele retorna uma subclasse da sua com o nome NomeClasse_enhancedByCGlib usando CGLib, então não deve ser tão problemático.[/quote]

Poisé, é complicado na hora do debug. O Hibernate retorna uns objetos estranhos, diferentes dos que eu persisti, deve ser justamente por causa do CGLib. O ideal é o que o NeoDatis faz hoje: retorna o objeto que eu persisti, do jeito que estava. Não fiz nenhum teste com ele ainda, talvez o exemplo do Estado, Cidade, Bairros e logradouros como citei não seja muito demorado. Preciso testar.

Oi André,

Para permitir esse lazy load, pelo que eu saiba não tem jeito vai ter que ser criando um subclasse da sua própria classe em tempo de runtime.

O Db4O tem o conceito de Activation onde vc pode definir a profundidade até qual vc quer carregar seus objetos. e ai não precisa gerar outra classe. Mas não fica tão ‘transparante’. Pq depois vc tem que ativar na mão os objetos.

O que vc acha?

[quote=Olivier]Oi André,

Para permitir esse lazy load, pelo que eu saiba não tem jeito vai ter que ser criando um subclasse da sua própria classe em tempo de runtime.

O Db4O tem o conceito de Activation onde vc pode definir a profundidade até qual vc quer carregar seus objetos. e ai não precisa gerar outra classe. Mas não fica tão ‘transparante’. Pq depois vc tem que ativar na mão os objetos.

O que vc acha?[/quote]

Porque não ficaria tão transparente? Como funciona exatamente o Activation do DB40?

[quote=Olivier]Oi André,

Para permitir esse lazy load, pelo que eu saiba não tem jeito vai ter que ser criando um subclasse da sua própria classe em tempo de runtime.

O Db4O tem o conceito de Activation onde vc pode definir a profundidade até qual vc quer carregar seus objetos. e ai não precisa gerar outra classe. Mas não fica tão ‘transparante’. Pq depois vc tem que ativar na mão os objetos.

O que vc acha?[/quote]

Dei uma olhada no Activation. Relamente, tenho que ativar na mão quando chego no nível limite definido. Não tem como o NeoDatis detectar quando chega nesse nível? O Hibernate detecta e popula o objeto.

André,

o conceito de Activation do Db4O até a versão 6 funciona assim. Vc pode dizer para o Db4O até qual profundidade vc quer carregar o grafo de objetos.
Por exemplo, no seu exemplo de Estada, se vc coloca activation depth igual a 1, Os objetos de tipo Estado serão carregados mas as cidades não, o getCidades retornará nulo. Mas vc ainda pode manualmente ativar as cidades. Por isso que falo que não é tão transparente, pq vc tem que fazer na mão. Na versão 7 do Db4o, eles já tem o que eles chamam de TransparentActivation, que é o que chamamos de lazy loading. E acho que fica melhor pq que o engine não carrega os objetos, mas qdo vc acessa um atributo (que não foi carregado) ele carrega na hora pelo seu OID.

Se tem como detectar e fazer o load automaticamente. Mas isso só usando byte para te retornar uma subclasse da sua classe onde os getters serão redefinidos da seguinte forma:

Classe original

public class Estado{
   private Collection cidades;

   public Collection getCidades(){
      return cidades;
   }
}

Classe gerada por byte code instrumention no runtime:

public class Estado_NeoDatis extends Estado{

   private OID cidadesOid;

   public Collection getCidades(){
      if(cidades==null){
         cidades = loadOnDemand(cidadesOid);
      }
      return super.getCidades();
   }
    
}

Ou seja, o NeoDatis estará retornando instâncias de Estado_NeoDatis em vez de Estado para ter o controle dos getters e fazer o lazy load.

[quote=Olivier]André,

o conceito de Activation do Db4O até a versão 6 funciona assim. Vc pode dizer para o Db4O até qual profundidade vc quer carregar o grafo de objetos.
Por exemplo, no seu exemplo de Estada, se vc coloca activation depth igual a 1, Os objetos de tipo Estado serão carregados mas as cidades não, o getCidades retornará nulo. Mas vc ainda pode manualmente ativar as cidades. Por isso que falo que não é tão transparente, pq vc tem que fazer na mão. Na versão 7 do Db4o, eles já tem o que eles chamam de TransparentActivation, que é o que chamamos de lazy loading. E acho que fica melhor pq que o engine não carrega os objetos, mas qdo vc acessa um atributo (que não foi carregado) ele carrega na hora pelo seu OID.

[/quote]

É justamente isso. O interessante é a transparência. Se o NeoDatis não depender do programador pra popular os subobjetos, seria interessante. Vou tentar baixar aqui na minha empresa e testar, to curioso pra ver como funciona.

Se vc quiser entender como funciona tb pode acessar http://neodatis-odb.wikidot.com/how-odb-works

Qualquer dúvida pode postar no source forge!

Valeu Andre!

[quote=Olivier]Se tem como detectar e fazer o load automaticamente. Mas isso só usando byte para te retornar uma subclasse da sua classe onde os getters serão redefinidos da seguinte forma:

Classe original

public class Estado{
   private Collection cidades;

   public Collection getCidades(){
      return cidades;
   }
}

Classe gerada por byte code instrumention no runtime:

public class Estado_NeoDatis extends Estado{

   private OID cidadesOid;

   public Collection getCidades(){
      if(cidades==null){
         cidades = loadOnDemand(cidadesOid);
      }
      return super.getCidades();
   }
    
}

Ou seja, o NeoDatis estará retornando instâncias de Estado_NeoDatis em vez de Estado para ter o controle dos getters e fazer o lazy load.
[/quote]

Dessa forma somente seria invocado o subobjeto quando chamado mesmo, certo? Mas pra isso, o programador teria que implementar uma classe filha Estado_NeoDatis, né?

Sim

Não, o NeoDatis fará isso automaticamente no runtime usando Byte Code instrumentation.