Pelo que eu andei mexendo e vendo, não consigo entender como é que a persistência poderia (ou não) ser transparente, porque nós sempre vamos ter que dizer pra aplicação quais objetos devem ser “mantidos”. Ela não pode adivinhar nem pode achar que só porque você chamou “new”, aquele objeto deve ser mantido, seria um desperdício de recursos.
Como é que fica a persistência transparente nessa? É não chamar método nenhum? É não amarrar os objetos a um “tipo” de persistência? Como é que eles vão ser reunidos?
Num sistema OO, todos os objetos não precisam ser salvos. Enquanto o objeto existir ele está acessível.
Acho que é claro para todos que isso não é viável, não existe memória para manter todos os objetos ativos ao mesmo tempo quando não estão sendo usados.
A solução é persistir em sistemas próprios (como bancos de dados). Isso é uma solução para driblar a limitação da plataforma que não atende ao paradigma.
O grande problema é que este conceito entranhado no seu sistema tira muitas das características OO dele a partir do momento que voce precisa se preocupar em quando persistir, quando salvar…
Persistencia transaprente eh ter certeza que seus objetos estao sempre a salvo sem rpecisar se preocupar com isso.
[quote=pcalcado]te conceito entranhado no seu sistema tira muitas das características OO dele a partir do momento que voce precisa se preocupar em quando persistir, quando salvar…
Persistencia transaprente eh ter certeza que seus objetos estao sempre a salvo sem rpecisar se preocupar com isso.
[/quote]
Mas eu não teria que, no mímino, dizer quais deveriam ser persistidos?
O que eu não to entendendo é o quão transparente a persistência “pode” ser. Porque se for pra não se preocupar, eu pego um pointcut no fim do contrutor e chamo um save, ninguém viu nada acontecer, mas eu vou ter “milhares” de objetos lá onde eles deveriam ser persistidos, eu ainda tenho que escolher quais devem ir. Escolher faz parte da transparência?
Não há escolha. Por definição, todo objeto ativo em memória (não elegível para GC no caso de Java) está automaticamente persistido. Se desligar e ligar a máquina, ele tem que estar lá.
A solução pratica é passivar os objetos, colocando em discos os menos ativos (o Space4J tinha uma implementação basica disso), e é bem possível de fazer com aspectos, o problema é quão performático e eficiente isso seria.
Por isso hoje eu penso que a única maneira de se obter é implementando diretamente na JVM ou provendo ganchos para isso.
Não bastaria ter uma referência para os objetos que eles continuariam lá? Se é pra ser transparente…
Eu li em algum lugar, mas eu não encontrei mais o link para colocar aqui, sobre persistencia pela JVM (era uma implementação de JVM), inclusive já trabalhando com dezenas de gigabytes de dados/objetos, em testes.
Existe comando de checkpoint simplesmente para sincronismo e recuperação posterior.
No texto ainda dizia que apenas os objetos em “uso” eram mantidos em memória RAM.
[quote=Dharis]
Eu li em algum lugar, mas eu não encontrei mais o link para colocar aqui, sobre persistencia pela JVM (era uma implementação de JVM), inclusive já trabalhando com dezenas de gigabytes de dados/objetos, em testes.
Existe comando de checkpoint simplesmente para sincronismo e recuperação posterior.[/quote]
Alguns bancos de dados OO suportam garbage collection, então teóricamente sim, você poderia salvar todos objetos sem problema. Ou no final da transação salvar somente os que tem chance de não serem coletados (referenciados pelo root set ou transitivamente duraveis)
Então vejamos, um objeto vai ficar elegível pro GC quando não houverem mais referências a ele dentro da aplicação nas threads correntes. Mas pra que alguém aponte pra ele, eu tenho que fazer uma atribuição ou chamar um método em algum lugar, pra colocar uma referência dele em um objeto que não esteja “elegível” GC.
Se chamar um método ou atribuir o objeto a algum lugar é “transparente”, então usar DAOs, repositórios, AR e essas coisas é transparente?
Acho que o maior problema não é descobrir, mas dizer, eu ainda não consigo imaginar como é que a minha aplicação vai advinhar que o objeto pode ser passivado ou, pior ainda, ser “pego” denovo.
Se tá tudo solto na VM, eu tenho que usar uma estrutura pra reunir eles, será que essa estrutura (ou repositórios) como você já disse, já não são transparentes não? Existe algum outro meio de se reunir objetos que não sejam estruturas de dados?
1 - A cada objeto criado, resitre ele numa estrutura qualquer
2 - Aplique um LRU e quando estiver sem memoria (um limite antes da memoria de verdade acabar, claro) passive os menos usados
Essa é a parte mais simples, que por si só já é complaxa.
Agora você vai ter que ter controle sobre todas as referências dos seus objetos, porque se alguem ficar segurando uma não adianta nada você passivar (o gc não chega nele). Vai ter que usar proxies no lugar dos objetos de verdade.
Acho interessante deixar para o usuário final escolher quando salvar… Tipo um cadastro de “Clichente”, com nome, endereço etc etc. Ao alterar um atributo, eu altero na classe de negóço, mas não mando salvar… só o botão “salva” vai persistir entende? Ou seja, criar os métodos de persistência e estender esse aspecto à interface com o usuário final. O que acha shoes? Muito idiota?
Então vejamos, um objeto vai ficar elegível pro GC quando não houverem mais referências a ele dentro da aplicação nas threads correntes. Mas pra que alguém aponte pra ele, eu tenho que fazer uma atribuição ou chamar um método em algum lugar, pra colocar uma referência dele em um objeto que não esteja “elegível” GC.
Se chamar um método ou atribuir o objeto a algum lugar é “transparente”, então usar DAOs, repositórios, AR e essas coisas é transparente?[/quote]
Eu falei que alguns bancos de dados usam GC, eu não falei em aplicações e threads. UM objeto em um OODBS fica elegivel de ser coletavel quando não for mais possivel encontrar ele a partir do root set. A mecânica é a mesma que com objetos em memoria no Java, mas falando de objetos em disco. Vale lembrar que isso não funciona muito bem nos OODBS que usam class-extents como root-set.
Isso no código se traduz no seguinte: al final da transação calcula-se quais objetos são transitivamente persistences e salva-se os que ainda não estão duraveis. É o mesmo esquema que o save-by-reachability que o Hibernate suporta.
OODBMS com GC são legais por alguns motivos, primeiro que acaba com o inferno de cascade-deletes e data-cleasing. Mas não muito legal para os paranóios em jamais perder qualquer tipo de informação.
[quote=louds]
OODBMS com GC são legais por alguns motivos, primeiro que acaba com o inferno de cascade-deletes e data-cleasing. Mas não muito legal para os paranóios em jamais perder qualquer tipo de informação.[/quote]
Não entendi, o banco OO implementa um GC? Ele controla as coisas a partir de um “root-set” (Prevayler???) e deleta um objeto por ele não fazer mais parte do grafo?
Eu já tive a minha experiência ruim com um OODBMS (Db4o) e realmente não acho que eles sejam a saída enquanto não houver um clone da SQL decente pra eles.
Sobre o estado Phillip, o Hibernate meio que controla isso, quando você “troca” as propriedades de um objeto “persistente” (que ainda está dentro de uma session) e faz um select, o Hibernate primeiro atualiza a tabela depois faz o select.