Olá pessoal,
Vou fazer uma introdução, um pouco comprida, mas necessária, para colocar a questão e para que possam me dar sugestões.
Já a algum tempo venho estudando e fazendo pesquisas sobre persistência em java. Estou usando já a muito tempo utlizando o hibernate, desde seus primordios (pre 1.0), estou muito satisfeito com ele, e recomendo ele a todos que tenham projetos mais simples do que o meu.
Iniciei um projeto para modelagem dinâmica de dados (Dynamic Model Beans), esse produto permite ao usuário criar/customizar beans de forma a modelar a sua informação em tempo real e com facilidade. Permitindo a criação de aplicaçoes customizáveis. Na primeira versão do software, utilizei o ASM (Byte Code Assembler) para gerar as classes dinamicamente, então gerava os arquivos XML de mapeamento do hibernate que seriam associados e carregados no startup, e o modelo é gravado pelo hibernate. Realmente muito confuso. Mas no final acabou funcionando e muito bem. A única coisa que deixou a desejar foi a necessidade de reiniciar o contexto da aplicação a cada vez que o modelo modelo dos objetos do domínio eram alterados, mesmo que só incluídos novos modelos, e ter muito cuidado, para nao mudar um tipo de uma propriedade para um tipo que nao houvesse conversao possivel diretamente.
Então durante os meses seguintes, novas questões foram aparecendo, e questões essas que não tinha como modelar de que as associações (quer eram muitas), fossem mapeadas em bancos de dados relacionais.
Então passei a fazer pesquisas na área de banco de dados orientado a objetos, procurando uma alternativa open source não GPL, com performance e estabilidade. Porém acabei em um beco sem saída, onde as ferramentas disponiveis eram todas comerciais, muito boas, mas caras, e muito longe do custo que o software teria que ter. Como exemplo , o banco de dados da Versant, que é um dos produtos top de mercado na área. Os testes que realizei com ele superaram todas as minhas expectativas/necessidades. É um banco de dados extremamente rápido, com uma curva de aprendizado mínima, e muito bem documentado, porém como disse CARO.
Vou listar as funcionalidades/dificuldade que existem para dar base pro projeto.
-
Durante o processo de captura/modelagem de dados, existem modelos de pouco uso, modelo pequenos (em sua maioria), ou ate extensos, que são pouco utilizados, e bem numerosos. Por exemplo se for usar o hibernate, teria que criar centenas de tabelas, e cada uma armazenaria pouquissimos registros.
-
Precisava externalizar instancias, utizando o padrão de proxies, para criar lazy accessors para instancias e associações, coleçoes etc, fiz isso utilizando o asm para criar extensoes das classes originais, porem o hibernate precisava acessar o seu Session (user) que tinha que ficar aberto. Para isso precisava criar um UUID no banco de dados, e uma tabela para fazer tracking das mudanças dos objetos, assim um usuario remoto poderia criar seu proprio cache de objetos, e dar refresh nesses objetos no estilo PUSH (HTTP). Isso acarretava mais um interceptor no hibernate para atualizar essa tabela.
-
Ter acesso às associações de cada instancia. Por exemplo: Tenho o objeto A, o A se auto-referencia e referencia o B, o B tem uma referencia a A e o A tem um java.util.List de B. Tenho o C que referencia a B, e o D que tem um java.util.List de A. É uma bagunça mesmo, é um modelo complexo, e um exemplo fictício. Quando um A for ser removido, preciso listar todos os relacionamentos que estão associados a esse A, e ter a opção de setar como nulo se for reference, remover de um coleção de for coleção, ou ate trocar por outra instancia do A. Então teria que guardar as associações de cada objeto. Já tentei com o hibernate usando interceptadores, mas o sistema ficou uma carroça.
-
No caso do hibernate, um polimorfismo muito profundo, aonde eu tenha A -> B -> C -> D -> E -> F, muito utilizado para extensoes no modelo do sistema original, faz com seja necessario muito joins, a nao ser que as informacoes estejam na mesma tabela (Single Table Hierarchy), com isso a execução de pesquisas em dominios complexos como esse ficam muito lentas. A extração de uma instância tmb (por ID), e a adminstração, ou seja alterar uma informação via SQL impossível.
-
Cheguei a utilizar o DB4O (GPL) porém como ele não tem suporte a tranções explicitas e ate mesmo utilizando JTA/JTS, não pude ir muito além.
-
O mais problemático. Para permitir o modelo Staging, aonde o usuário pode definir um conjunto de instancias ativas, como existe em varios CMS, seria necessário implementar o padrão HOLDER/INSTANCE, aonde o holder teria o UUID e a ligação ao conjunto de versões e a instancia atual.
Tente imaginar esse padrão em um banco de dados relacional, seria algo com 3 a 4 vezes mais tabelas. E muito lento. Ate mesmo em um OODB seria algo irracional, seriam muitos relacionamentos para obter a verão corrente de uma instância.
Com todos esses requisitos, e sem uma luz no final do túnel, comecei a fazer pesquisas para desenvolvimento de um banco de dados orientado a objetos em JAVA com todas as funcionalidades que desejava, e estou no meio do projeto nesse momento. Porém e um projeto a longo prazo, deve demorar por volta de 2 a 3 anos para chegar a ser estável. Pretendo colocar ele como open source sob a licensa Apache 2.0. Então estou organizando o que tenho hoje, tenho muito code snippet ainda e pouca documentação para colocar o projeto no java.net, para que todos possam ajudar a avançar com o projeto.
Denominei esse banco de dados como Java Hyper Storage, ele é muito rápido utliza Persisters para evitar a utilização de reflexão, são criados Persisters que acessam diretamente as propriedades dos objetos, parecido com o processo de Class Enhancement do JDO, porém sem alterar o class original do objeto. É uma extensão do class original, que é retornado pelo Storage Engine, quando um objeto é gravado.
Ele utiliza um sistema de arquivamento em páginas de tamanho fixo, anexadas a indices do tipo bitmap, aonde o cluster pode ser definido pelo usuário ao criar o database.
Criei também um modelo de healing, em caso de falhas, aonde as páginas originais são copiadas para um novo file storage para evitar corrompimento em caso de power failure, ou desligamento da jvm.
Esse modelo de paginação é bem leve, cada transação criada é associada a um novo file storage com suas proprias paginas, fazendo referencia as paginas do bd original ou a transações anteriores, de forma que é possivel criar transações em cascata.
Foi criado um sistema de back log, aonde as alterações feitas no banco de dados podem ser enviadas por rede, ou a um arquivo de log com checkpoint, para em caso de corrompimento do bd ele possa ser reestabelecido em seu último estado garantido.
O query engine dele funciona com native queries, aonde é possivel criar um query (class) que implemente NativeQuery (interface), entao essa classe pode ser enviada ao servidor (Client/Server), para ser utilizada. É muito parecido com stored procedures. Porém esses Native Queries são muito rápidos e podem ser colocados em modo Updatable, nesse modo ele cria um index, com os registros filtrados, e permite a utilização de cursores no lado do servidor.
Também implementei o modelo Query por exemplo (Q.B.E) e o S.O.D.A…
Estou na parte de model evolution, que detecta a modificação nas classes e cria novas entradas no bd, atualizando as instancias gravadas quando são carregadas. Para isso criei um interceptor, que permite redefinir o modelo usando java, implementando uma interface (ModelAdapter) que são registradas no bd.
Migrei todo o código de persitência para NIO, ganhando ate 40% de performance, e um load bem menor até 60% de redução em processamento de tarefas mais complexas.
Pretendo criar um road map no projeto, e preciso que quem quiser contribuir com sugestões, participação ativa, ou até mesmo que descorde da necessidade do projeto responda a tópico.
Grato,