Você está na página 1de 34

Prevayler

1. Quem voc, Klaus Wuestefeld?


o criador e um dos desenvolvedores deste projeto (framework) que atua na
prevalncia de informaes
2. O que ele , e quais os objetivos / metas que ele pretende alcanar.
O Prevayler a camada de prevalncia livre para Java. Prevalncia a arquitetura
natural a se utilizar em qualquer sistema que tenha memria RAM suficiente para
conter todos os seus dados. O Prevayler no tem meta nenhuma porque medida em
que a memria RAM vai ficando mais barata, torna-se inevitvel a adoo gradual da
prevalncia. s uma questo de tempo.

3. Como o pblico brasileiro e estrangeiro tem visto este projeto? Tens recebido o apoio
esperado?
O Prevayler muito mais usado na Alemanha (talvez por causa do meu nome) e nos EUA. O
brasileiro muito deslumbrado com o que vem de fora. Santo de casa no faz milagre.
Sim. No Brasil, recebi bastante apoio do pessoal do DFJug, SouJava, da revista MundoJava e do
prprio JavaFree. As palestras sobre o Prevayler tambm so muito bem recebidas na maioria dos
evento de Java e software livre.
4. O conceito de Prevalncia ainda um susto para as pessoas?
O Prevayler a cura para um cncer que as pessoas nem sabem que tm. Nossa comunidade de
desenvolvedores de software est to atrofiada com o uso do banco de dados que a maioria das
pessoas no faz a menor idia do que seja OO de verdade. O pior que acham que sabem.
5. Partindo para perguntas mais tcnicas, o que o Java 5 com funcionalidades como o
Generics, pode trazer de til para os desenvolvedores que usarem o Prevayler?
Todas as funcionalidades do Java 5 podem e devem ser usadas nas aplicaes prevalecentes porque
seus objetos de negcios so todos objetos Java 100 % nativos. O mesmo no pode ser dito de
aplicaes que salvam seus objetos em bancos de dados, a no ser que inventem um banco de dados
com suporte a " generics ", por exemplo.
Essa uma vantagem do Prevayler para a qual eu no tinha me atentado ainda. As aplicaes
podem imediatamente tirar vantagem de qualquer inovao na linguagem; e acredito que teremos
muitas daqui para frente, por causa da concorrncia com. NET.
6. O que voc acha dos frameworks de mapeamento Objeto / Relacional, de especificaes
como o EJB 3.0 e os bancos de dados OO? Eles ainda tem alguma chance contra o Prevayler?
So melhores que nada, por um lado, porque facilitam a vida do desenvolvedor. So
extremamente prejudiciais, por outro lado, porque fazem muitos desenvolvedores pensarem
que OO s ler e escrever objetos burros. Quantas vezes voc j viu algum usar o " observer
design pattern ", por exemplo, em objetos mapeados para um banco de dados relacional? E o
" state pattern "? E o " visitor pattern "? Qualquer " pattern "? triste.
A medida que a memria RAM vai se tornando cada vez mais barata, acredito ser inevitvel a
adoo gradual da prevalncia. Existem barreiras de ignorncia e de medo muito grandes a serem
vencidas, porm, e, at l, as tecnologias que voc mencionou vo continuar incrustadas na cabea
de muito gerente retranqueiro (vide COBOL). Somos como os bebs nascidos dentro da Matrix:
brutalmente atrofiados pelo uso de banco de dados. Passar a usar a prevalncia uma sensao
parecida com a do Neo: " Meus olhos doem. ". Morpheus responde: " porque voc est usando-os
pela primeira vez. "
7. Voc ainda usa banco de dados?
Infelizmente sim. Ainda serei obrigado a usar um banco de dados sempre que no tiver RAM
suficiente para algum de meus sistemas. Isso ocorre principalmente em dispositivos mveis (PDAs,
celulares, etc) e sistemas embarcados. Mesmo assim, quero aproveitar o mximo da OO que Java
me oferece, sem ficar restrito a registros burros em tabelas. Preciso que o banco de dados seja o
mais leve e transparente possvel. com esse intuito que estou trabalhando no db4o . Ele tem 4
anos de estrada e acabou de tornar-se livre atravs da GPL.
8. O sistema operacional feito em java, JNode, poder fazer uso do Prevayler. Qual a sua
opinio sobre isso? Vai dar certo? O prevayler poder atender a todas as necessidades de um
SO?
Eu no usaria o Prevayler nesse caso. Para usar o Prevayler necessrio que a aplicao disponha
de RAM suficiente para conter todos seus dados. Devido ao declnio constante do preo da memria
RAM, esse j o caso para muitas aplicaes, mas ainda no para um SO genrico.
9. Existe algo que voc gostaria de mudar na especificao do java para facilitar a vida dos
desenvolvedores do Prevayler?
A Serializao padro do Java poderia ser melhorada no sentido de suportar melhor a evoluo do
esquema de objetos (alterao na estrutura das classes).
10. J existe algo planejado como uma lista de novas caractersticas para o Prevayler 3?
A novidade mais legal do Prevayler 3 vai ser a replicao tolerante a falhas. As aplicaes vo
poder rodar em modo " cluster " sem alterar uma linha de cdigo sequer. A replicao normal j
pode ser experimentada no Prevayler 2.
11. Determinados sistemas so to fortemente acoplados a SQL que se tornam difceis de
serem convertidos para uma abordagem OO. Em alguns, uma nica consulta no banco de
dados possui mais de 500 linhas, vrias funes de clculo sobre os valores e mais de 15
tabelas relacionadas. O que voc diria aquelas pessoas que possuem esse tipo de sistema e
querem migrar para o OO usando o Prevayler?
Inicialmente, vo sentir-se como o Neo, boiando naquela gua, completamente atrofiados por terem
vivido a vida inteira dentro de uma bolha de banco de dados. Aos poucos, vo exercitar sua nova
liberdade e seus msculos vo se desenvolver. Ento, quando me disserem: " I know OO ", vou
ansiosamente responder: " Show me ".
12. Caractersticas:
Implementado em Java e portado para vrias outras linguagens, o Prevayler a camada original de
prevalncia de sistemas. Prevalncia compreende persistncia e replicao transparentes dos dados
ou objetos de negcios de um sistema. Isso significa que podemos criar objetos Java comuns na
RAM, usando uma VM Java qualquer, e persist-los sem termos que alterar uma linha de cdigo
sequer. Em outras palavras, o Prevayler fornece aos nossos objetos de negcio uma Invulnerable
Virtual Machine (IVM). Livranos da complexidade do EJB; das limitaes do SQL; do peso do
JDBC; da licena, instalao e administrao do SGBD; dos scripts de instalao do banco de dados
e, principalmente, permite que comecemos a usar OO de verdade.
Persistncia Transparente para Java.
9983 VEZES mais rpido que o ORACLE.
3251 VEZES mais rpido que o MySQL.
Imagine que voc pudesse escrever suas classes em Java puro.
Imagine que seus objetos fossem persistidos de forma transparente: sem SQL, sem JDBC e sem nada de EJB.
Imagine que, de quebra, seu sistema ainda ganhasse tolerncia a falhas e balanceamento de carga.
Imagine isso tudo rodando VRIAS VEZES MAIS RPIDO que em um banco de dados convencional.
Imagine que isso pudesse ser feito usando um simples software livre.

14. Qual a diferena entre o Prevayler e os bancos de dados tradicionais?


Primeiro, a desvantagem: por persistir objetos Java comuns, o Prevayler requer que tenhamos RAM
suficiente para conter todos os nossos objetos de negcio. Ou seja, no vivel ainda usar a
prevalncia em sistemas com dezenas ou centenas de gigabytes, embora isso seja apenas uma
questo de tempo. Para sistemas com centenas de megas at alguns gigas de dados, porm, j
perfeitamente possvel usar o Prevayler. Agora, as vantagens: o Prevayler de mil a dez mil vezes
mais rpido que um banco de dados e no nos restringe quanto arquitetura, algoritmo, estrutura de
dados e linguagens de consulta que podemos usar em nossas aplicaes. Pense no seu banco de
dados como uma priso. Algumas pessoas gostam da priso porque l ganham gororoba. O
Prevayler no d de comer, mas d a liberdade de voc escolher a sua comida. triste, mas a
maioria das pessoas est to acomodada gororoba da priso que morreria de fome assim que
ganhasse a liberdade.
JSF com Prevayler

Aplicaes ultra rpidas e sem quebra de encapsulamento. Neste artigo veremos alguns problemas
que bancos de dados relacionais impem em sistemas orientados a objetos e como resolv-los
utilizando o Prevayler.
De que se trata o artigo:
Neste artigo veremos alguns problemas que bancos de dados relacionais impem em sistemas
orientados a objetos e como resolv-los utilizando o Prevayler. Tambm veremos os principais
conceitos e funcionalidades do mesmo e como podemos utiliz-lo com o JSF 2.
Em que situao o tema til:
til principalmente em sistemas com consultas intensivas, como o caso da maioria dos sistemas
Web. Com o Prevayler, as consultas chegam a ficar 10.000 vezes mais rpidas que bancos de dados
relacionais. Alm disso, voc pode utilizar todo o poder da orientao a objetos sem se preocupar
com os detalhes restritivos de persistncia. Dessa forma seus sistemas ficaro mais simples, mais
velozes e mais manutenveis.
Resumo DevMan:
O Prevayler uma biblioteca de persistncia que grava seus objetos na forma em que deveriam ser
gravados: como objetos (e no como tuplas). No h mapeamento em tabelas, configurao de
servidor de bancos de dados, nem restrio do que voc pode utilizar em seu modelo de negcios.
Tenha todo o poder da orientao a objetos sem se preocupar com os detalhes de persistncia. No
artigo, explicado como podemos utilizar essa biblioteca com o JSF 2.
O desenvolvimento de aplicaes orientadas a objetos (OO) que utiliza bancos de dados relacionais
para persistir seus objetos de negcio tem uma srie de implicaes. Uma delas a quebra de
encapsulamento. Ela acontece porque os dados podem ser manipulados irrestritamente por meio da
SQL. Para amenizar esta situao, voc pode at criar setters e getters para os atributos de suas
classes, mas isso no significa nada para o banco de dados. Um UPDATE, por exemplo, no ir
respeitar aquela regra de negcio fundamental que voc implementou no mtodo set.
Outro problema com o uso de bancos de dados relacionais a restrio que eles impem em seus
objetos de negcio. Voc no pode estruturar seus objetos de qualquer jeito; tem que ser de um jeito
mapevel em tabelas e preferencialmente da forma mais simples possvel, como o formato classe-
tabela e atributo-coluna. E aqui est outro problema: o tempo computacional gasto com a converso
de objetos para tuplas e vice-versa. No entanto, embora existam alguns padres de projeto para isso,
o fato que seus objetos de negcio, na maioria das vezes, devem seguir regras limitantes, como
implementar uma interface ou estender uma classe, e os mtodos devem seguir um padro de
nomenclatura.
Devido a estes fatores, alguns desenvolvedores criam o esquema de banco de dados para depois
criar as classes; outros, por sua vez, criam as classes e depois as tabelas. Na primeira alternativa,
pode-se arriscar em dizer que as classes resultantes utilizaro somente 10% de todo o poder da OO.
So classes anmicas. Na segunda alternativa, o mapeamento para tabelas poder no ser trivial,
podendo ser feito somente com alguns ajustes afinal, impossvel mapear esses dois
paradigmas (OO e relacional) sem perder alguma coisa. Esses problemas fazem parte de um
conjunto maior, denominado de Object-relational impedance mismatch (algo como
incompatibilidade objeto-relacional).
Deste modo, alguns acreditam que sistemas de informao utilizam pouqussimas funcionalidades
da OO porque a persistncia de dados feita de maneira no-OO, e.g. em bancos de dados
relacionais. O Prevayler, contudo, fornece uma maneira de persistir seus objetos como eles
deveriam ser persistidos: como objetos, e no como tuplas. Assim, seus objetos podem ter a
estrutura, os nomes de mtodos e os tipos de atributos que quiser. O sistema fica muito mais rpido
porque os objetos esto sempre em sua forma nativa no h a necessidade de converter tuplas,
tipos, etc. A rapidez importante principalmente em sistemas web, j que a maioria deles
orientada a consultas, ou seja, consultas so muito mais frequentes que incluses.
Uma grande parte do mercado usa o JavaServer Faces para criar sistemas web. De forma simplista,
o JSF um framework em que as pginas web so criadas pela composio de componentes e que
oferece uma forma simples de comunicao entre esses componentes e os objetos de negcio. Tal
comunicao feita utilizando managed beans, que so objetos com tempo de vida (ou escopo)
predeterminado.
O JSF 2 trouxe uma srie de novidades, dentre elas a navegao implcita, em que torna facultativa
a especificao de regras de navegao no faces-config.xml, bastando apenas especificar a URL.
Outra novidade o escopo View, em que o managed bean continua vivo enquanto a aplicao
estiver na mesma pgina, o que no possvel com o escopo Request porque a cada submisso um
novo bean criado. Esse escopo timo para utilizar AJAX, o que, alis, outra inovao no JSF 2.
Neste contexto, vamos aprender a construir uma aplicao simples em JSF 2 utilizando as
novidades supracitadas e tendo o Prevayler como framework de persistncia de dados. Veremos as
principais funcionalidades do Prevayler e como utiliz-las em JSF.
Prevayler
Prevayler um framework open source de persistncia inicialmente desenvolvido pelo brasileiro
Klaus Wuestefeld. O framework oferece uma alternativa ao famigerado Mapeamento Objeto-
Relacional, implementado por vrios frameworks de persistncia, como o Hibernate. Quando se
utiliza esse mapeamento, os objetos de negcio ficam presos semntica do banco de dados
relacional, impedindo o uso de todo o poder da Orientao a Objetos (OO) e frequentemente
quebrando parte do encapsulamento. Com o Prevayler, no precisamos mapear os objetos de
negcio s tabelas do banco de dados porque simplesmente no h tabelas e nem mesmo banco de
dados. Todos os objetos so mantidos vivos na memria RAM!
Mas e se o servidor der pane ou acabar a energia? No tem problema. Periodicamente (toda noite,
por exemplo), todos os objetos so serializados em um arquivo chamado de snapshot. E se o
servidor cair antes do snapshot ser criado? Perderei todas as alteraes feitas? No. Todas as
alteraes (i.e. incluso, excluso e alterao) tambm so registradas em disco antes de serem
executadas. Ao ligar o computador novamente, o ltimo snapshot carregado e todas as alteraes
so executadas na mesma ordem em que ocorreram.
A quantidade de informaes que voc pode guardar est limitada ao tamanho da sua memria
RAM. Para muitas aplicaes, isso no chega a ser um problema. De modo geral, os objetos Java
ocupam bem menos espao na RAM do que quando persistidos em um banco de dados relacional.
Imagine que um objeto Cliente, por exemplo, ocupe 256 bytes na memria. Ter um milho de
clientes significa cerca de 244 MB e isso representa menos de 6% de uma modesta memria de 4
GB.
Em um teste de escalabilidade e resultados, enquanto o Prevayler, open source, retorna 228.369 queries por
segundo, um sistema Oracle responde de forma 9983 vezes mais lenta que o Prevayler. Voc acreditaria nesse clculo
impressionante? Esse , contudo, um dos projetos de software livre brasileiros mais conhecidos no mundo.
Klaus Wuestefeld pioneiro de Extreme Programming no Brasil e criador do Prevayler.
O Prevayler a implementao do conceito de prevalncia. E a prevalncia o terceiro mecanismo de persistncia
mais simples possvel, Em sua palestra com o provocativo nome Voc ainda usa banco de dados?, na segunda

edio do encontro NoSQLBr, em So Paulo, Klaus fez uma apresentao bastante inusitada dos conceitos que
permeiam o produto. Preocupou-se mais em fornecer uma breve introduo sobre o que vem a ser esse pattern de

prevalncia de sistemas 1 mil a 10 mil vezes mais rpido que um banco de dados relacional para, em seguida, listar
as perguntas do pblico presente sobre a eficincia do Prevayler.
Ele anotou uma a uma e defendeu o uso do Prevayler com base nas seguintes contestaes:
- Schema Evolution
- Dependncia de um sistema externo
- Dados sem schema
- Meu sistema ir crescer 300 mil vezes
- OLAP / Anlise
- Clustering
- Sistema pesado em escrita
- Ambiente hbrido / Vrios sistemas acessando os mesmos dados
- Paralelismo, concorrncia
- Corrupo de dados
- Alta disponibilidade
- Segurana
E as duas perguntas mais intrigantes de todas:
1. Por que no tem mais gente usando?
2. Quem vai me ajudar se der tudo errado?
As respostas para essas e outras questes sobre o Prevayler, incluindo as caractersticas que definem sua persistncia
e espelhamento transparentes e transaes ACID ridiculamente simples, voc v em detalhes no vdeo com a ntegra
da palestra de Klaus Wuestefeld no NoSQLBr 2011:

http://www.gonow.com.br/blog/2011/10/31/klaus-wuestefeld-e-o-prevayler-afinal-por-que-voce-ainda-usa-banco-de-
dados/

Fcil, simples, orientado a objetos, sem instalao e configurao de outros servios. So


muitas as qualidades do Prevayler. Se voc gostou da verso 1.0 voc vai se maravilhar
com a 2.0, que ainda est em testes mas j est muito estvel.
Para baixar a verso 2.0 do Prevayler utilize o link:
http://sourceforge.net/project/showfiles.php?group_id=36113 e baixe a verso mais
atual, quando este tutorial foi liberado era a 2.02.002
Quem baixar a nova verso ir notar que no foram adicionadas muitas classes. Dentre as
novas caractersticas esto a replicao (Replication) de base de dados e a serializao em
XML.

Tutorial Prevayler 2
Vitor Pamplona

Este artigo uma recompilao de trs tutoriais que fiz em 2004, quando o Prevayler 1 ainda era a
release default.
Todos ns estamos pra l de acostumados com os tradicionais bancos de dados relacionais. Em
java, trabalhar com esse tipo de armazenamento de dados no to fcil. Se voc no pensar em
uma boa arquitetura para a sua aplicao, o seu cdigo fonte fica horrvel, principalmente se voc
um daqueles que adora digitar comandos SQL no meio do cdigo Java.
Mas, vamos l! Quais so as principais diferenas entre os bancos de dados relacionais e o
Prevayler? Simples, o Prevayler no um banco de dados, portanto, no tem as caractersticas de
um, como: controle de acesso, compartilhamento de dados, integridade, interface via SQL, etc. O
Prevayler um simples gravador e recuperador de objetos. Voc manda gravar e ele grava,
simples.
Muitas pessoas tem medo do Prevayler em aplicaes grandes pela falta da SQL. Isso mesmo, se
voc vai usar o Prevayler, voc no poder executar SQLs em seu sistema. Ao invs disso, quem
faz a lgica da busca o prprio programador, ou seja, o programador faz tudo. Se insistir, voc
pode usar o JoSQL para fazer consultas na base do Prevayler.
Vamos a um breve exemplo. Digamos que voc queira fazer um sistema que salve somente o nome
das pessoas. Como voc um programador que gosta de um desenvolvimento caprichado, voc ir
criar uma classe Pessoa, contendo apenas o atributo nome. Como essa abaixo:
1. public class Pessoa {

2. private String nome;

3. public Pessoa(String nome) {

4. this.nome = nome;

5. }

6.
7. public String getNome() {

8. return nome;

9. }

10. public void setNome(String nome) {

11. this.nome = nome;

12. }
13.}
Alm disso, voc definir de uma classe para armazenar as pessoas que voc j anotou.
1. import java.util.ArrayList;

2. import java.util.List;

3.
4. public class ListaPessoas {

5. private List<Pessoa> listaPessoas = new ArrayList<Pessoa>();

6.
7. public void add(Pessoa pes) {

8. listaPessoas.add(pes);

9. }

10. public Pessoa get(int i) {

11. return listaPessoas.get(i);

12. }

13. public int size() {

14. return listaPessoas.size();

15. }
16.}
Pronto. Mas e agora, como iremos armazenar isso? J pensou em uma tabela de banco? Ok, pode
ser feito tambm, mas voc reparou no trabalho que isso vai lhe custar? Comprar ou baixar um
banco de dados (lembre-se da licena dupla) e instal-lo e criar a tabela. Se pensarmos no
Prevayler, como seria? Muito mais simples. Voc s precisaria criar uma classe para o mtodo add
da sua lista de pessoas. Vejamos.
Antes de mais nada crie um projeto Java na sua IDE preferida. Baixe o jar mais atual do repositrio
do Prevayler e coloque-o em seu classpath.
Primeiro passo no uso do Prevayler implementar Serializable nas classes que sero persistidas:
Pessoa e Lista Pessoas. Permita-me explicar o que Serializao. Quando voc tem um objeto
instanciado, ele pode no estar armazenado sequencialmente na memria. Por esse motivo existe a
serializao, que nada mais do que colocar os valores que o objeto est utilizando juntamente com
suas propriedades de uma forma que fique seqencial, um nico stream de dados. Tornando um
objeto, estamos atribuindo essa qualidade a ele, e dando privilgios para que o mesmo possa ser
gravado em disco ou enviado por rede (Serial - Bit a Bit).
Ao criar uma classe serializvel deve-se definir a constante serialVersionUID, que controlar a
verso da classe. Este nmero nunca deve mudar. Se ele mudar, ou se o programador no defin-lo
e a classe for re-compilada, o java no importar os dados da classe salvos, pois no saber tratar a
mudana do versionamento da classe.
A ListaPessoas ficar assim:
1. ...
2. public class ListaPessoas implements Serializable {

3. private static final long serialVersionUID = 1L;

4. private List<Pessoa> listaPessoas = new ArrayList<Pessoa>();

5. ...
E a Pessoa:
1. ...
2. public class Pessoa implements Serializable {

3. private static final long serialVersionUID = 2L;

4. private String nome;

5. ....
No se esquea de importar Serializable em ambas as classes.
Em seguida, vamos criar a nossa transao, a AdicionaPessoa, que tambm ser serializada e ir
adicionar uma pessoa em nossa base:
1. import java.io.Serializable;

2. import java.util.Date;

3.
4. import org.prevayler.Transaction;

5.
6. public class AdicionaPessoa implements Transaction, Serializable {

7. private static final long serialVersionUID = 3L;

8. private String nome;

9.
10. public AdicionaPessoa(String nome) {

11. this.nome = nome;

12. }

13.
14. public void executeOn(Object businessSystem, Date date) {

15. ((ListaPessoas) businessSystem).add(new Pessoa(nome));

16. }
17.}
O tudo que estiver dentro do mtodo executeOn ser uma transao ACID do Prevayler. Desta
forma, todo que est dentro desta funo ser executado uma nica vez e por completo. Caso haja
uma excesso dentro deste mtodo, o Prevayler retorna a verso da base que ele salvou
automaticamente ao chamar o mtodo execute. Este mtodo tambm sincronizado, ou seja, o
Prevayler s permite uma execuo de transao por vez.
Para testar, crie uma classe Main como esta:
1. import java.io.BufferedReader;

2. import java.io.IOException;

3. import java.io.InputStreamReader;

4.
5. import org.prevayler.Prevayler;

6. import org.prevayler.PrevaylerFactory;

7.
8. public class Main {

9.
10. static Prevayler prevayler;

11.
12. public static void main(String[] args) throws IOException, ClassNotFoundException
{
13. System.out.println("Iniciando Prevayler...");

14.
15. PrevaylerFactory factory = new PrevaylerFactory();

16. factory.configurePrevalenceDirectory("BASE");

17. factory.configurePrevalentSystem(new ListaPessoas());

18. prevayler = factory.create();

19.
20. System.out.print("Digite nome da pessoa ou FIM para sair: ");

21. String nome = lerTeclado();

22. while (!nome.equals("FIM")) {

23. try {

24. prevayler.execute(new AdicionaPessoa(nome));

25. } catch (Exception e1) {

26. e1.printStackTrace();

27. }

28. System.out.println("Pessoa armazenada.");

29. System.out.print("Digite o nome da pessoa ou FIM para sair: ");

30. nome = lerTeclado();

31. }

32.
33. System.out.println("Imprimindo pessoas persistidas.");

34. ListaPessoas lista = ((ListaPessoas) prevayler.prevalentSystem());

35. for (int i = 0; i < lista.size(); i++) {

36. System.out.println(lista.get(i).getNome());

37. }

38. }

39.
40. public static String lerTeclado() {

41. BufferedReader reader = new BufferedReader(new InputStreamReader(

42. System.in));

43. try {

44. return reader.readLine();

45. } catch (IOException e1) {

46. return "FIM";

47. }

48. }
49.}
As primeiras linhas do programa criam o mecanismo de persistncia do Prevayler com a base de
dados apontando para um diretrio chamado BASE. Note que informado a classe que controla
todo o banco de dados. E esta classe o programador quem define. Em seguida o programa l um
conjunto de nomes e os persiste no banco. Por ltimo, imprime todos os nomes cadastrados.
Repare que voc pode fechar o programa a qualquer hora, em qualquer circunstncia. Os dados
ficaro armazenados corretamente. Se voc no acredita, de um reset no micro bem na hora de ele
salvar os dados. Se vc verificar a pasta BASE ir encontrar alguns arquivos. journal. Estes so os
arquivos onde as transaes, no nosso caso instncias da AdicionaPessoa, so salvos. Por
enquanto, o Prevayler est salvando s as transaes e no o banco por completo. Ao iniciar, o
Prevayler re-executa todas as transaes e o seu banco estar no mesmo estado que vc o deixou
na ltima execuo.
Este um exemplo bem simples, lembre-se que se voc for implementar algo profissionalmente com
o prevayler, voc deve conhecer alguns padres de projeto. Eles sero necessrios para que se
faa uma boa programao e torne possvel uma futura manuteno.

Snapshots
Apesar de prtico, re-executar os logs um processo lento. Para evitar, podemos tirar, a qualquer
momento, um screenshot da base e salv-lo em disco. Este processo se chama Snapshot. Quando
um snapshot feito, o prevayler no precisa mais executar as transaes anteriores ao Snapshot,
diminuindo o tempo de carga. A classe abaixo uma thread que faz snapshots da base atravs do
mtodo takeSnapshots de 6 em 6 horas.
1. import java.io.IOException;

2.
3. import org.prevayler.Prevayler;

4.
5. public class SnapshotTimer extends Thread {

6. Prevayler prevayler;

7.
8. public SnapshotTimer(Prevayler prevayler) {

9. this.prevayler = prevayler;

10. this.setDaemon(true);

11. }

12.
13. public void run() {

14. super.run();

15.
16. while (true) {

17. try {

18. Thread.sleep(1000 * 60 * 60 * 6); //6 horas

19. prevayler.takeSnapshot();

20. System.out.println("Snapshot disparado as " + new java.util.Date() +


"...");
21. } catch (InterruptedException e) {
22. e.printStackTrace();

23. } catch (IOException e) {

24. e.printStackTrace();

25. }

26. }

27. }
28.}
Para utiliz-la, basta adicionar a linha abaixo na classe Main, aps o mtodo create da
PrevaylerFactory:
1. new SnapshotTimer(prevayler).start();
Pronto. Voc j pode testar. Note que existir um arquivo. snapshot no diretrio BASE do prevayler.

Mudanas nas classes Serializveis


Apesar de simples, o Prevayler exige que o desenvolvedor mantenha a compatibilidade das classes
de dados. Na carga dos dados, o java ir verificar quais os atributos da classe ainda existem, e
estes sero carregados. Os dados de atributos removidos ou renomeados so jogados fora. Os
novos atributos sero inicializados com seus valores default. A ordem dos atributos no interessa,
portanto voc pode alterar a ordem que no haver nenhum problema. A serializao salva e busca
com o nome do atributo. Por isso mesmo que o nome no pode ser alterado.
Vc poder encontrar mais informaes sobre isso neste post. Mas recomendo fortemente que vc
teste vrias alteraes nas classes serializveis em vrios contextos para identificar as mensagens
de erro.

Replicao
O Prevayler 2 suporta replicao de base, instncias do seu sistema podero trabalhar em uma
base nica de maneira transparente. A replicao mantm todas as informaes em todos os
computadores com acesso (por isso o nome Replication), e todas as transaes so executadas em
todos os computadores. Tudo isso transparente, basta configurar de maneira adequada.
Lembra-se da classe PrevaylerFactory? Observe o cdigo de um servidor de Replication:
1. PrevaylerFactory factory = new PrevaylerFactory();

2. // Configura o objeto principal da persistncia

3. factory.configurePrevalentSystem(new ListaPessoas());

4. // Configura o diretrio para manter os dados em disco


5. factory.configurePrevalenceBase("Base");
6. // Informa que esta instncia um servidor de replicao
7. factory.configureReplicationServer(PrevaylerFactory.DEFAULT_REPLICATION_PORT);
8. // Cria o prevayler
9. Prevayler prevayler = factory.create();
E agora o cdigo de um cliente:
1. PrevaylerFactory factory = new PrevaylerFactory();

2. // Configura o objeto principal da persistncia

3. factory.configurePrevalentSystem(new ListaPessoas());
4. // Configura o diretrio para manter os dados em disco

5. factory.configurePrevalenceBase("Base");

6. // Informa onde se encontra o servidor de replicao

7. factory.configureReplicationClient("192.168.0.200",
PrevaylerFactory.DEFAULT_REPLICATION_PORT);
8. // Cria o prevayler

9. Prevayler prevayler = factory.create();

Agora basta criar uma forma de dizer, ao executar o Main, quem cliente e quem servidor, chamar
os mtodos certos e pronto!

Prevayler: Persistncia totalmente OO.

Se voc participa de alguma comunidade Java, certamente j ouviu falar no Prevayler


(http://www.prevayler.org). Mas, voc sabe o que e como ele faz a persistncia? Se voc um dos
muitos que responderam no a esta pergunta, aqui est um artigo explicando como trabalhar com o
Prevayler.
Todos ns estamos pra l de acostumados com os tradicionais bancos de dados relacionais. Em java,
trabalhar com esse tipo de armazenamento de dados no to fcil. Se voc no pensar em uma
boa arquitetura para a sua aplicao, o seu cdigo fonte fica horrvel, principalmente se voc um
daqueles que adora digitar comandos SQL no meio do cdigo Java.
Mas, vamos l! Quais so as principais diferenas entre os bancos de dados relacionais e o
Prevayler? Simples, o Prevayler no um banco de dados, portanto, no tem as caractersticas de
um, como: controle de acesso, compartilhamento de dados, integridade, interface via SQL, etc. O
Prevayler um simples gravador e recuperador de objetos. Voc manda gravar e ele grava,
simples.
Muitas pessoas tem medo do Prevayler em aplicaes grandes pela falta da SQL. Isso mesmo, se
voc vai usar o Prevayler, voc no vai poder executar SQLs em seu sistema. Ao invs disso, quem
faz a lgica da busca o prprio programador, ou seja, o programador faz tudo.
Vamos a um breve exemplo. Digamos que voc queira fazer um sistema que salve somente o nome
das pessoas. Como voc um programador que gosta de um desenvolvimento caprichado, voc ir
criar uma classe Pessoa, contendo apenas o atributo nome. Como essa abaixo:
public class Pessoa {
private String nome;
public Pessoa(String nome) {
this.nome = nome;
}

public String getNome() {


return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
}
Alm disso, ir precisar de uma classe para armazenar as pessoas que voc j anotou.
import java.util.ArrayList;
public class ListaPessoas {
private ArrayList listaPessoas = new ArrayList();
public void add(Pessoa pes) {
listaPessoas.add(pes);
}
public Pessoa get(int i) {
return (Pessoa) listaPessoas.get(i);
}
public int size() {
return listaPessoas.size();
}
}
Pronto, mas e agora, como iremos armazenar isso? J pensou em uma tabela de banco? Ok, pode
ser feito tambm, mas voc reparou no trabalho que isso vai lhe causar?? Comprar ou baixar um
Banco de dados e instal-lo (coisa que as vezes no muito fcil) e criar a tabela. Ser que a
melhor sada?
Se pensarmos no Prevayler, como seria? Resposta: Muito mais simples. Voc s precisaria criar uma
classe para o mtodo add da sua lista de pessoas. Vejamos como fica?
Antes de mais nada baixe o jar prevayler-1.02.001.jar do prevayler no seguinte
endereohttp://www.ibiblio.org/maven/prevayler/jars/e coloque-o em seu classpath.
Detalhe: O jar para fazer a persistncia tem somente 12 KB.
Agora vamos para as implementaes em nossas classes. Primeiramente estenda a sua
ListaPessoas da classe AbstractPrevalentSystem do prevayler. Indicando que esta classe ser o
nosso controle de armazenamento.
Aps, mude a classe Pessoa para implementar a interface Serializable. Ou seja, a classe pessoa,
conter os valores que iremos gravar. Portanto serializvel.
Logo aps crie a classe abaixo:
import java.io.Serializable;
import org.prevayler.Command;
import org.prevayler.PrevalentSystem;

public class AdicionaPessoa implements Command {


private String nome;
public AdicionaPessoa(String nome) {
this.nome = nome;
}
public Serializable execute(PrevalentSystem system) throws Exception {
((ListaPessoas) system).add(new Pessoa(nome));
return null;
}
}
A interface Command indicar ao sistema do Prevayler que o mtodo execute ir alterar a base de
dados, que ele dever tratar o command como uma transao e ele dever persistir as mudanas.
Pronto! Nosso sistema que grava o nome das pessoas j est pronto. Para testar, crie uma classe
Main como esta:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.prevayler.implementation.SnapshotPrevayler;

public class Main {


public static void main(String[] args) {
System.out.println("Iniciando Prevayler...");
SnapshotPrevayler prevayler = null;

try {
prevayler = new SnapshotPrevayler(new ListaPessoas());
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

System.out.print("Digite nome da pessoa ou FIM para sair: ");


String nome = lerTeclado();
while (!nome.equals("FIM")) {
try {
prevayler.executeCommand(new AdicionaPessoa(nome));
} catch (Exception e1) {
e1.printStackTrace();
}
System.out.println("Pessoa armazenada.");
System.out.print("Digite o nome da pessoa ou FIM para sair: ");
nome = lerTeclado();
}

System.out.println("Imprimindo pessoas persistidas.");


ListaPessoas lista = ((ListaPessoas) prevayler.system());
for (int i = 0; i < lista.size(); i++) {
System.out.println(lista.get(i).getNome());
}
}
public static String lerTeclado() {
BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in));
try {
return reader.readLine();
} catch (IOException e1) {
return "FIM";
}
}
}
A classeSnapshotPrevayler um gerenciador dos teus objetos, ele cuidar para que seus objetos
sejam persistidos em disco para evitar falhas de queda de energia por exemplo.
A linha "prevayler.executeCommand(new AdicionaPessoa(nome));" indica ao Prevayler que voc
est adicionando uma nova pessoa com o nome no parmetro. Ele dever persistir o dados para
futuras consultas.
Repare que voc pode fechar o programa a qualquer hora, em qualquer circunstncia. Os dados
ficaro armazenados corretamente. (Se voc no acredita, de um reset no micro bem na hora de ele
salvar os dados )
Este um exemplo bem simples, lembre-se que se voc for implementar algo profissionalmente
com o prevayler, voc deve conhecer alguns padres de projeto. Eles sero necessrios para que se
faa uma boa programao e torne possvel uma futura manuteno.

Atualizaes verso 2.0:

Ausncia da AbstractPrevalentSystem
No prevayler 1.0 era necessrio manter uma classe responsvel por conter os dados a
serem persistidos. Esta classe, que no primeiro tutorial era implementada
pela ListaPessoas, deveria herdar da classe AbstractPrevalentSystem da API do Prevayler.

Isso no mais necessrio, a classe AbstractPrevalentSystem deixou de existir, abrindo alas


para um conjunto de outras especificaes. Basicamente, voc continua necessitando de
uma classe central de dados, como a ListaPessoas. Esta classe ser utilizada pela
interface Prevayler que agregar a sua classe fazendo a persistncia da mesma sem
necessitar de herana de qualquer outra classe.

De Command para Transaction


No Prevayler 1.0 existia a interface Command, que deveria ser implementada pelas
transaes do sistema, ns implementamos a classeAdicionaPessoa no primeiro tutorial.
Esta classe era persistida como logs, possibilitando a "prevalncia" das informaes
mesmo em queda de energia.

J na nova verso, as coisas ficaram mais claras. A classe AdicionaPessoa deve


implementar a interface Transaction para permitir o log das informaes pela
classe PersistentLogger. A classe Command foi renomeada.
PrevaylerFactory
Seguindo o Design Pattern Abstract Factory a classe PrevaylerFactory foi criada para
instanciar o Prevayler propriamente dito, deixando de lado um cdigo que antes era
assim:
1. SnapshotPrevayler prevayler = new SnapshotPrevayler(new NumberKeeper(), "demo1"<im
g src="http://javafree.uol.com.br/forum/images/smiles/icon_wink.gif">;

para torn-lo mais "correto" e explorar a liberdade dessa maneira:


1. Prevayler prevayler = PrevaylerFactory.createPrevayler(new NumberKeeper(), "demo1"<im
g src="http://javafree.uol.com.br/forum/images/smiles/icon_wink.gif">;

A nos prximos itens veremos algumas novas possibilidades com esse estilo de cdigo.

XmlSnapshotManager
Na verso 2.0 foi adicionada a classe XmlSnapshotManager que far a persistncia dos
objetos em XML e no em arquivos binrios como faz a serializao original da Sun. Esta
implementao permite que seus dados fiquem visveis a qualquer editor, podendo ser
importado para tratamentos personalizados, alm de ser um arquivo com um padro
totalmente aberto.

SnapshotManager
a classe que far a persistncia de suas informaes em arquivos binrios, padro do
Java. Esta classe tambm deve ser utilizada caso voc queira criar um novo modelo de
persistncia, como foi feito com a classe XmlSnapshotManager visto acima que herda desta
classe. Que tal implementar uma persistncia para arquivos TXT?

Replication Server e Client


O Prevayler 2 suporta replicao de base. O que isto? Simples, um banco de dados
normal pode ser acessado por vrios micros em uma rede, agora o prevayler tambm
pode sem que voc tenha que fazer nenhum esforo. A diferena que ele mantm as
informaes em todos os micros (por isso o nome Replication), mas mantm um dos
micros como principal, os outros recebero as mudanas instantaneamente aps serem
persistidas.

Qual a complexidade para usar isso? Nenhuma. Isso mesmo, como todo o Prevayler,
utilizar replicao mais simples que criar uma classe. Veremos isso no exemplo a
seguir:

Lembra-se da classe PrevaylerFactory? Ela cria a classe Prevayler para a persistncia, de


uma olhada nesse cdigo, que um cdigo para iniciar o Prevayler de uma aplicao sem
Replication:
1. PrevaylerFactory factory = new PrevaylerFactory();
2. // Configura o objeto principal da persistncia
3. factory.configurePrevalentSystem(new ListaPessoas());
4. // Configura o diretrio para manter os dados em disco
5. factory.configurePrevalenceBase("Base"<img src="http://javafree.uol.com.br/forum/images/
smiles/icon_wink.gif">;
6. // Cria o prevayler
7. Prevayler prevayler = factory.create();

Bom, agora observe o cdigo de um servidor de Replication:


1. PrevaylerFactory factory = new PrevaylerFactory();
2. // Configura o objeto principal da persistncia
3. factory.configurePrevalentSystem(new ListaPessoas());
4. // Configura o diretrio para manter os dados em disco
5. factory.configurePrevalenceBase("Base"<img src="http://javafree.uol.com.br/forum/images/
smiles/icon_wink.gif">;
6. // Informa que esta instncia um servidor de replicao
7. factory.configureReplicationServer(PrevaylerFactory.DEFAULT_REPLICATION_PORT);
8. // Cria o prevayler
9. Prevayler prevayler = factory.create();

Simplesmente bastou inserir a penltima linha.

E agora, o cdigo de uma aplicao cliente de Replication:


1. PrevaylerFactory factory = new PrevaylerFactory();
2. // Configura o objeto principal da persistncia
3. factory.configurePrevalentSystem(new ListaPessoas());
4. // Configura o diretrio para manter os dados em disco
5. factory.configurePrevalenceBase("Base"<img src="http://javafree.uol.com.br/forum/images/
smiles/icon_wink.gif">;
6. // Informa onde se encontra o servidor de replicao
7. factory.configureReplicationClient("192.168.0.200", PrevaylerFactory.DEFAULT_REPLIC
ATION_PORT);
8. // Cria o prevayler
9. Prevayler prevayler = factory.create();

Bastou alterar a penltima linha.

isso, somente isso! Ridiculamente simples.

Exemplo: Implementando o armazenamento de pessoas com o Prevayler 2.0


Vamos colocar a mo na massa? Muito bem, vamos criar um sistema que armazena
nomes de pessoas, muito simples, mas ser o necessrio para entendermos a lgica do
Prevayler. Este o mesmo exemplo dos tutoriais anteriores, porm tratando replication
com Prevayler 2

1 - Lista pessoas sem a implementao de AbstractPrevalentSystem, porm


implementando Serializable
1. import java.io.Serializable;
2. import java.util.ArrayList;
3.
4. public class ListaPessoas implements Serializable {
5. private ArrayList listaPessoas = new ArrayList();
6.
7. public void add(Pessoa pes) {
8. listaPessoas.add(pes);
9. }
10.
11. public void remove(Pessoa pes) {
12. listaPessoas.remove(pes);
13. }
14.
15. public Pessoa get(int i) {
16. return (Pessoa) listaPessoas.get(i);
17. }
18.
19. public int size() {
20. return listaPessoas.size();
21. }
22.}

2 - A classe pessoa, sem modificao da verso 1.0


1. import java.io.Serializable;
2.
3. public class Pessoa implements Serializable {
4.
5. public static final long serialVersionUID = 1L;
6.
7. private String nome;
8.
9. public Pessoa(String nome) {
10. this.nome = nome;
11. }
12.
13. public String getNome() { return nome; }
14. public void setNome(String nome) { this.nome = nome; }
15.
16.}

3 - A classe AdicionaPessoa, trocando a implementao de Command por Transaction.


1. import java.util.Date;
2.
3. import org.prevayler.Transaction;
4.
5. public class AdicionaPessoa implements Transaction {
6.
7. private static final long serialVersionUID = 1L;
8.
9. private String nome;
10.
11.
12. public AdicionaPessoa(String nome) {
13. super();
14. this.nome = nome;
15. }
16.
17. public void executeOn(Object system, Date arg1) {
18. ((ListaPessoas)system).add(new Pessoa(nome));
19. }
20.}

4 - A classe SnapshotTimer criada no tutorial 2 para controlar o tempo entre os


Snapshots.
1. import java.io.IOException;
2. import org.prevayler.Prevayler;
3.
4. public class SnapshotTimer extends Thread {
5.
6. Prevayler prevayler;
7.
8. public SnapshotTimer(Prevayler prevayler) {
9. this.prevayler = prevayler;
10. }
11.
12. public void run() {
13. super.run();
14.
15. try {
16. while (true) {
17. Thread.sleep(1000 * 5);
18. prevayler.takeSnapshot();
19. //System.out.println("Snapshot disparado as " + new java.util.Date() + "..."<img
src="http://javafree.uol.com.br/forum/images/smiles/icon_wink.gif">;
20. }
21. } catch (InterruptedException e) {
22. e.printStackTrace();
23. } catch (IOException e) {
24. e.printStackTrace();
25. }
26. }
27.}

5 - Por timo a classe Main, que cria o Prevayler baseado em parmetros que so
passados ao executar a aplicao. Quatro funces foram adicionadas, uma para retornar
uma Factory default, e as outras trs so para cada tipo de aplicao: Standalone,
Replication Server e Replication Client.
1. import java.io.BufferedReader;
2. import java.io.IOException;
3. import java.io.InputStreamReader;
4.
5. import org.prevayler.Prevayler;
6. import org.prevayler.PrevaylerFactory;
7.
8. public class Main {
9.
10. public static void main(String[] args) {
11.
12. System.out.println("Iniciando Prevayler..."<img src="http://javafree.uol.com.br/forum/i
mages/smiles/icon_wink.gif">;
13.
14. Prevayler prevayler = null;
15. SnapshotTimer snapshot = null;
16. try {
17. if (args.length == 0)
18. prevayler = getPrevayler();
19. else if (args[0].equalsIgnoreCase("server"<img src="http://javafree.uol.com.br/foru
m/images/smiles/icon_wink.gif">)
20. prevayler = getPrevaylerServer();
21. else if (args[0].equalsIgnoreCase("client"<img src="http://javafree.uol.com.br/forum
/images/smiles/icon_wink.gif">)
22. prevayler = getPrevaylerClient();
23. else
24. prevayler = getPrevayler();
25. snapshot = new SnapshotTimer(prevayler);
26. snapshot.start();
27. } catch (IOException e) {
28. e.printStackTrace();
29. } catch (ClassNotFoundException e) {
30. e.printStackTrace();
31. }
32.
33. System.out.print("Digite o nome da pessoa ou FIM para sair: "<img src="http://javafre
e.uol.com.br/forum/images/smiles/icon_wink.gif">;
34. String nome = lerTeclado();
35. while (!nome.equals("FIM"<img src="http://javafree.uol.com.br/forum/images/smiles/i
con_wink.gif">) {
36. try {
37. prevayler.execute(new AdicionaPessoa(nome));
38. } catch (Exception e1) {
39. e1.printStackTrace();
40. }
41.
42. System.out.println("Pessoa armazenada.\n"<img src="http://javafree.uol.com.br/foru
m/images/smiles/icon_wink.gif">;
43. System.out.print("Digite o nome da pessoa ou FIM para sair: "<img src="http://javaf
ree.uol.com.br/forum/images/smiles/icon_wink.gif">;
44.
45. nome = lerTeclado();
46. }
47.
48. snapshot.interrupt();
49. System.out.println("\n Imprimindo pessoas persistidas.\n"<img src="http://javafree.uol.
com.br/forum/images/smiles/icon_wink.gif">;
50. ListaPessoas lista = ((ListaPessoas)prevayler.prevalentSystem());
51. for (int i=0; i<lista.size(); i++) {
52. System.out.println(lista.get(i).getNome());
53. }
54.
55. }
56.
57. public static String lerTeclado() {
58. BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
59. try {
60. return reader.readLine();
61. } catch (IOException e1) {
62. return "FIM";
63. }
64. }
65.
66. /**
67. * Cria um objeto Prevayler para aplicao normal - Sem replicao
68. */
69. public static Prevayler getPrevayler() throws IOException, ClassNotFoundException {
70. System.out.println("Instanciando Prevayler normal"<img src="http://javafree.uol.co
m.br/forum/images/smiles/icon_wink.gif">;
71. return getPrevaylerFactory().create();
72. }
73.
74. /**
75. * Cria um objeto Prevayler para ser um servidor de replicao
76. */
77. public static Prevayler getPrevaylerServer() throws IOException, ClassNotFoundExceptio
n{
78. System.out.println("Instanciando o Servidor"<img src="http://javafree.uol.com.br/fo
rum/images/smiles/icon_wink.gif">;
79. PrevaylerFactory factory = getPrevaylerFactory();
80. // Informa que esta instncia um servidor de replicao
81. factory.configureReplicationServer(PrevaylerFactory.DEFAULT_REPLICATION_PO
RT);
82. // Cria o prevayler
83. return factory.create();
84. }
85.
86. /**
87. * Cria um objeto Prevayler para ser um cliente de replicao
88. */
89. public static Prevayler getPrevaylerClient() throws IOException, ClassNotFoundExceptio
n{
90. System.out.println("Instanciando o Cliente"<img src="http://javafree.uol.com.br/for
um/images/smiles/icon_wink.gif">;
91. PrevaylerFactory factory = getPrevaylerFactory();
92. // Informa onde se encontra o servidor de replicao
93. factory.configureReplicationClient("localhost", PrevaylerFactory.DEFAULT_REPLIC
ATION_PORT);
94. //
95. factory.configurePrevalenceBase("BaseClient"<img src="http://javafree.uol.com.br/for
um/images/smiles/icon_wink.gif">;
96. // Cria o prevayler
97. return factory.create();
98. }
99.
100. public static PrevaylerFactory getPrevaylerFactory() {
101. PrevaylerFactory factory = new PrevaylerFactory();
102. // Configura o objeto principal da persistncia
103. factory.configurePrevalentSystem(new ListaPessoas());
104. // Configura o diretrio para manter os dados em disco
105. factory.configurePrevalenceBase("Base"<img src="http://javafree.uol.com.br/forum/i
mages/smiles/icon_wink.gif">;
106. return factory;
107. }
108.
109.}

Para testar execute a classe Main. Para abrir um servidor de replicao, passe como
parmetro server, para criar um cliente de replicao, passe como parmetro client.

Agora s colocar a mo na massa e imaginar aplicaes super poderosas!

isso pessoal, o poderoso Prevayler se resume a uma palavra: Simplicidade. o


necessrio para criarmos uma bela aplicao.

-----------------------------------------------------------------------------------------------------

Mudei o seu exemplo pra nao permitir a inclusao de nomes repetidos. Basicamente, atiro uma
excecao quando incluir o nome repetido.
Mudei o metodo add de ListaPessoa para atirar uma excecao quando for incluido um nome que jah
existe. Em seguida, faco o catch dessa excecao no executeOn da classe AdicionaPessoa.
O problema eh que a excecao nao eh gerada. Ele simplesmente ignora e cadastra normalmente,
como se nao houvesse tratamento. A outra duvida eh como fazer essa excecao passar para a
aplicacao e tratar lah. O metodo executeOn nao permite atirar excecoes... Como eu faria para
colocar um throws Exception lah?
E a ultima duvida (estou abusando, neh?) eh que rodei o seu exemplo e quando eu digito FIM (ou
seja, quando termina a execucao) apos imprimir os nomes, aparece a seguinte mensagem de erro:

java.lang.InterruptedException: sleep interrupted


at java.lang.Thread.sleep(Native Method)
at SnapshotTimer.run(SnapshotTimer.java:17)

[quote="takeda"]O metodo executeOn nao permite atirar excecoes... Como eu faria para colocar um
throws Exception lah?

Use RuntimeException ou alguma outra unchecked.

valeuz...
_________________
Porm o tutorial no d dicas sobres os erros de execuo.
J configurei o classpath de tudo quanto jeito. As classes esto no mesmo diretrio. O que falta
mais? SORTE?

Iniciando Prevayler...

Instanciando Prevayler normal

Digite o nome da pessoa ou FIM para sair: LEO

java.lang.ClassNotFoundException: de.preclipse.AdicionaPessoa

at java.net.URLClassLoader$1.run(URLClassLoader.java:199)

at java.security.AccessController.doPrivileged(Native Method)

at java.net.URLClassLoader.findClass(URLClassLoader.java:187)

at java.lang.ClassLoader.loadClass(ClassLoader.java:289)

at java.lang.ClassLoader.loadClass(ClassLoader.java:235)

at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302)

at java.lang.Class.forName0(Native Method)

at java.lang.Class.forName(Class.java:219)

at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:55

at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1513)

at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1435)

at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1626)

at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)

at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324)

at
org.prevayler.implementation.snapshot.SnapshotManager.readSnapshot(SnapshotManager.java:114)

at org.prevayler.implementation.snapshot.SnapshotManager.deepCopy(SnapshotManager.java:136)

at org.prevayler.implementation.PrevaylerImpl.deepCopy(PrevaylerImpl.java:93)

at org.prevayler.implementation.PrevaylerImpl.execute(PrevaylerImpl.java:5

at de.preclipse.Main.main(Main.java:43)

java.lang.RuntimeException: Unable to produce a deep copy of the transaction. Deep copies of


transactions are executed instead of the transactions themselves so that the behaviour of the system
during transaction execution is exactly the same as during transaction recovery from the log.

at org.prevayler.implementation.snapshot.SnapshotManager.deepCopy(SnapshotManager.java:139)

at org.prevayler.implementation.PrevaylerImpl.deepCopy(PrevaylerImpl.java:93)

at org.prevayler.implementation.PrevaylerImpl.execute(PrevaylerImpl.java:5Pessoa armazenada.

Digite o nome da pessoa ou FIM para sair:

at de.preclipse.Main.main(Main.java:43)

FIM

Imprimindo pessoas persistidas.

java.lang.InterruptedException: sleep interrupted

at java.lang.Thread.sleep(Native Method)

at de.preclipse.SnapshotTimer.run(SnapshotTimer.java:31)

_________________
JavaFree.org
1.
lcmetzger
Posts:330

Publicado em: 09/04/2009 23:18:44

java.lang.ClassNotFoundException: de.preclipse.AdicionaPessoa

Mas este no um problema do Prevayler!

A classe AdicionaPessoa no est sendo encontrada no CLASSPATH...


revise sua aplicao...

_________________
Luiz Carlos Metzger
Blumenau - SC
1.
Crash_overried
Posts:17
Calma, no se desespere....

A classe Adiciona pessoa est no package de.preclipse?


Algo deve estar errado!

Veja o item 3 do tutorial, a classe AdicionaPessoa no pertence a package algum. Procure revisar o
tutorial com calma, de nada adiantaria
eu lhe enviar um CLASSPATH que no corresponda com o que vc precisa.

Tentei executar em um terminal dos e apareceu esse mesmo erro que aparece no eclipse.
J li e reli o tutorial vrias vezes. Note que quando compilo erro algum aparece, somente quando
executo aparece o erro. Engraado que chega executar porm quando vai instanciar AdicionaPessoa
d o erro, mas mesmo assim o programa continua.
As classes esto no mesmo diretrio, ento o que devo fazer???

Vc j executou esse exemplo do Vitor ( Migrando a persistencia - prevayler 2.0 )

1 - No caso do Prevayler 2, o lance do PrevaylerFactory, o objetivo armazenar uma Factory de


Objetos? Por exemplo, alm de eu armazenar o ListaPessoas, eu posso adicionar ListaPessoas,
ListaClientes, ListaProdutos, ou seja, todos que meu sistema for trabalhar? e no final, o Prevayler
ter todos os objetos na sua Factory e vai saber com qual trabalhar? (como o SessionFactory do
Hibernate)?.

No! Voc ter que criar uma classe para manter todas essas listas:
1. class MinhaPersistencia {
2. private Set listaPessoas;
3. private Set listaClientes;
4. private Set listaProdutos;
5. private Set listaXXX;
6. }

2 - Sobre gerao de LOG e Snapshot. Os logs so gerados todas as vezes que ocorre modificao
dos objetos e o Snapshot quando o programador ativa ele, certo? O que eu pude perceber em alguns
testes, que o gerado vrios e vrios arquivos de log, enquanto apenas um de snapshot, significa
que para fazer um backup, eu posso apenas salvar o Snapshot, certo?

Certo. Certo, desde que voc no tenha transaes executadas depois do snapshot.

3 - Ainda sobre arquivos de log. O que eu percebi, que o arquivo gerado aps a finalizao do
processo (no caso gravar um novo Objeto). A nvel de produo, o correto no seria abrir o
PrevaylerFactory no inicio do sistema e s fech-lo quando o sistema for fechado? (como que se faz
ocm o Hibernate tambm). Nesse tempo que ele est aberto, no tem perigo de perder as
informaes com queda de energia? eu falo isso, pois vamos supor um sistema que o processo fica
aberto o dia todo...

O log salvo no momento da Transao, e no depois de fechar o sistema. Voc deixa o objeto
criado pelo Prevayler Factory aberto at o final da execuo do sistema

4 - Poderia explicar melhor o que est sendo feita nessa linha?


Cdigo:
((ListaPessoas)system).add(pessoas);

Ela adiciona uma nova pessoa na sua lista de pessoas. Esta linha est no Transaction, pois ela ser
re-executada se o prevayler precisar recarregar os logs. Sacou? ela vai adicionar uma pessoa na sua
lista.

5 - As consultas so feitas pelo programador, ele que faz as regras. Significa que por exemplo, eu
queria pegar todos os Clientes que possuem idade entre 10 e 30 anos (supondo que eu tenho um
atributo idade do tipo int), eu terei que pegar a ListaClientes com todos os Clientes, rodar o
ArrayList 1 por 1 e ir fazendo IF em cada um para testar, caso esteja no intervalo que eu queira, eu
jogo para um outro ArrayList por exemplo? Isso no muito mais trabalhoso em um sistema de
grande porte, onde simples SQL (SQL para consulta, select...) no mais simples.. Alm do que, a
maioria dos clientes precisam de valores na hora, onde um simples SQL e um Gerenciador de
Banco de Dados mostre esses dados, enquanto com Prevayler vou ter que fazer isso
manualmente.....

Vai ter que fazer isso sim. Existem alguns frameworks que filtram colees de dados. Podes usar
um deles tambm. Ou, faa um ndice com o HashMap para essas consultas. Nesse caso o prevayler
fica realmente mais complexo.

6 - Pra terminar essa primeira parte (acredito que ter outras partes Rolling Eyes ), voc mostrou
como adicionar um novo objeto, mas como funciona o processo de Excluir e at mesmo Atualizar
os Dados de um Objeto j gravado?

Voc ter que criar uma transaction para cada uma das outras opes que voc adicionar...

Sobre a Pergunta 1, eu vou ter que criar uma classe que ir conter a lista das outras classes, no
exemplo MinhaPersistencia. Ento no PrevaylerFactory, invs de adicionar cada classe, eu adiciono
a MinhaPersistencia? (ser que viajei? poderia talves dar um exemplo com cdigo?).

Isso mesmo
A questo da 5, voc indica alguma framework dessa para testar? Eu digo isso, pois a maioria dos
meus sistemas, os clientes geralmente necessitam de informaes no momento, e com SQL
funciona legal. Hoje mesmo em um sistema de hospital, me pediram a quantidade de pacientes que
estao em tratamento entre 14 e 29 anos separados por tipo de doena. com um simples SQL eu
mostrei essas informaes para o pessoal.
Na mundo Java desse mes tem uma exelente aplicao para fazer isso chamada SAMBUR.

Pergunta 6 ficou a dvida na primeira vez que eu li. Eu at tinha percebido que iria ter que criar
uma nova Transaction, mas no sabia como implement-la.. pensando um pouco mais e fiz uns
testes aqui e funcionou

Agora uma questo mais de arquitetura.


Supondo que tenho meu Modelo Pessoas, para ela tenho minha ListaPessoas, agora para fazer a
operao de gravao e excluso, terei ter que criar 2 classes para Transaes diferentes (ex.
AdicionaPessoa, http://www.javafree.com.br/forum/posting.php?
mode=quote&p=62371RemovePessoa)???? Se for assim, acho que um sistema com vrios modelos,
ter MUITA classe para controle.
Talves uma dica de arquitetura bem vinda..

Use DAOs e aglutine as Transaes semelhantes em classes semelhantes. Lembre-se de separar as


camadas de Persistncia e view. Transaction e PrevaylerFactory so da persistncia e nada mais.

De uma olhada nos cdigos do BabaXP (http://www.babaxp.org), l est bem separado, inclusive
com uma arquitetura que deixa a opo para utilizar Prevayler ou banco de dados via DAOs.

Eu vi alguns arquivos fontes do BabaXP e eu tive a idia certa de como usar o DAO nesse caso.
A nica coisa chata que eu ainda achei, o lance de criar vrias classes de Transaction (la no projeto
tb est assim, ou seja, tem o CreateCustomer, DeleteCustomer, UpdateCustomer) e o DAO que
chama qual classe dependendo da ao.

necessrio implementar cada um desses por causa do Log. E isso at um Design Pattern (Vide:
Command).
_________________

Galera como fao para excluir um objeto no prevayler, estou usando uma lista de objetos ja removi
da lista atraves do comando
( ((Lista)prevayler.prevalentSystem).remove(cod));
Funciona porem quando reinicio o programa, alteracao nehuma ocorreu, o objeto esta la novamente,
como resolvo isso ?

Isto est numa transaction

Vou iniciar um pequeno projeto aqui internamente na empresa utilizando o Prevayler e Struts, eu e
um amigo meu comeamos a modelar os packages, classes e etc do Sistema.
Gostaria de uma opinio sua, sobre os packages.
Temos um package chamado dao, onde ter uma classe chamada DAO que ter o PrevaylerFactory
apenas. No mesmo package, cada funcionalidade ter seu DAO, como por
exemplo PessoasDAO que ir herdar do DAO tendo assim o PrevaylerFactory e mais mtodos de
insert, delete, update, etc etc etc..... ficou legal assim?
Outra coisa, estavamos vendo aqui, e invs de usar um ArrayList para armazenar os modelos (como
no exemplo do tutorial), seria legal usar um TreeMap, pois teriamos uma Key (que poderia ser o ID
da pessoa que nunca se repete) alm de estar sempre ordenado por essa ID, certo?
_________________
JavaFree.org
1.
vfpamp
Posts:6098

Publicado em: 09/04/2009 23:18:44

[quote="JuniorSP"]Vou iniciar um pequeno projeto aqui internamente na empresa utilizando o


Prevayler e Struts, eu e um amigo meu comeamos a modelar os packages, classes e etc do
Sistema.
Gostaria de uma opinio sua, sobre os packages.
Temos um package chamado dao, onde ter uma classe chamada DAO que ter o PrevaylerFactory
apenas. No mesmo package, cada funcionalidade ter seu DAO, como por
exemplo PessoasDAO que ir herdar do DAO tendo assim o PrevaylerFactory e mais mtodos de
insert, delete, update, etc etc etc..... ficou legal assim?

Arquitetura muito "pessoal" do projeto. Mas acho que vai ficar legal.

[quote="JuniorSP"]
Outra coisa, estavamos vendo aqui, e invs de usar um ArrayList para armazenar os modelos (como
no exemplo do tutorial), seria legal usar um TreeMap, pois teriamos uma Key (que poderia ser o ID
da pessoa que nunca se repete) alm de estar sempre ordenado por essa ID, certo?

Corretssimo, TreeMap ou um HashMap voc cria uma lista indexada otimizando, e muito, as
consultas.
_________________
Vitor Pamplona
http://vitorpamplona.com
@vitorpamplona
1.
JuniorSP
Posts:18

Publicado em: 09/04/2009 23:18:44

Ol Vtor

Agora eu acho que a ltima pergunta de todas

Todos os exemplos que eu fiz, foi em aplicao standalone, ontem comecei uma aplicao para
rodar com Struts no Tomcat. Eu configurei o mtodo configureBaseSystem("Base", pensando que
na raiz do projeto seria criado um diretrio Base e dentro ficaria os arquivos binrios do Prevayler,
mas para minha surpresa no.
No Windows 2000 foi criado dentro do diretrio WinNT/System32...., no Windows XP caiu dentro
do diretrio Eclipse, ou seja, cada SO ta colocando o base em um local diferente, hehehe.

Gostaria que ficasse na raiz do meu projeto, mas no gostaria de por um caminho absoluto para
isso, tem jeito ?

Valeu e desculpa pelo encmodo ops:


_________________
JavaFree.org
1.
JuniorSP
Posts:18

Publicado em: 09/04/2009 23:18:44

1. public class RemovePessoa implements Transaction {


2. private Pessoas pessoas;
3. public RemovePessoa(Pessoas pessoas) {
4. this.pessoas = pessoas;
5. }
6. public void executeOn(Object system, Date arg1) {
7. System.out.println(pessoas.getNome());
8. ((ListPessoas)system).remove(pessoas);
9. }
10.}

Teoricamente esse Cdigo era pra remover a pessoa certo? (lembrando que o objeto pessoas est
OK, pois o System.out.println est retornando o nome correto da pessoa.

Obs: eu j fiz um delete e funcionou, esse aqui para apresentar pro meu chefe no funcionou ops:
_________________
JavaFree.org
1.
vfpamp
Posts:6098

Publicado em: 09/04/2009 23:18:44

Como voc est executando ele?


_________________
Vitor Pamplona
http://vitorpamplona.com
@vitorpamplona
1.
JuniorSP
Posts:18

Publicado em: 09/04/2009 23:18:44

[quote="vfpamp"]Como voc est executando ele?

1. prevayler.execute(new RemovePessoa(pessoas));

_________________
JavaFree.org
1.
vfpamp
Posts:6098

Publicado em: 09/04/2009 23:18:44

[quote="JuniorSP"][quote="vfpamp"]Como voc est executando ele?

1. prevayler.execute(new RemovePessoa(pessoas));

Eu hein... da uma analisada nas duas situaes... alguma coisa de diferente deve ter...
_________________
Vitor Pamplona
http://vitorpamplona.com
@vitorpamplona
1.
JuniorSP
Posts:18

Publicado em: 09/04/2009 23:18:44

Descobri

o mtodo remove(Object..) no estava removendo do Prevayler, agora se eu usar remove(int index),


ae funciona normal.
Esse talves foi meu ltimo teste utilizando ArrayList, agora no sistema oficial, iremos utilizar
HashMap ou TreeMap

valeu pela ajuda


_________________
JavaFree.org
1.
hlfsousa
Posts:1

Publicado em: 09/04/2009 23:18:44

A chamada snapshot.interrupt() vai lanar exceo quase sempre por causa do Thread.sleep(...).
Para evitar isso, basta modificar o cdigo do SnapshotTimer para que ele seja avisado formalmente
de quando deve parar:
1. import java.io.IOException;
2. import org.prevayler.Prevayler;
3.
4. public class SnapshotTimer extends Thread {
5.
6. Prevayler prevayler;
7. private boolean running;
8.
9. public SnapshotTimer(Prevayler prevayler) {
10. this.prevayler = prevayler;
11. this.running = true;
12. }
13.
14. public void stopTimer() {
15. this.running = false;
16. }
17.
18. public void run() {
19. super.run();
20.
21. try {
22. while (running) {
23. Thread.sleep(1000 * 5);
24. prevayler.takeSnapshot();
25. //System.out.println("Snapshot disparado as " + new java.util.Date() + "..
."<img src="http://javafree.uol.com.br/forum/images/smiles/icon_wink.gif">;
26. }
27. } catch (InterruptedException e) {
28. e.printStackTrace();
29. } catch (IOException e) {
30. e.printStackTrace();
31. }
32. }
33.}

e trocar a chamada de snapshot.interrupt() para snapshot.stopTimer(). Isso deve resolver o problema


das excees. Na verdade no um problema, que a exceo tratada com e.printStackTrace().
Mas se voc gosta de uma sada graciosa, est a a sugesto.
1.
ablm
Posts:1

Publicado em: 09/04/2009 23:18:44

Gostei bastante do tutorial, mto bom

Fiquei to impressionado com o prevayler que estou a pensar em migrar uma aplicacao existente de
Visual Basic/Access para Java/Prevayler.

E aqui se coloca o meu principal problema.

Algum sabe como posso converter a minha base de dados access para objectos java? E vice-versa
(uma vez que posso precisar de voltar a usar a aplicao antiga, caso surja algum problema)?

Basicamente, se conseguir arranjar uma soluo para isto, passo logo a usar o Prevayler

Cya
_________________
JavaFree.org
1.
arof
Posts:1

Publicado em: 09/04/2009 23:18:44

Cya,

sobre o seu problema acho que ter que montar um mapeamento entre a sua base atual e objetos de
negcios para fazer a migrao. mapear o modelo relacional da base para os objetos que voc
possui.

Aproveitando a mensagem, peo ajuda:

Estou querendo desenvolver um projeto de base de dados com conceitos de prevalencia aqui na
empresa para acelerar o nosso tempo de resposta.

A lgica de negcios complexa e envolve dados financeiros com tratamento estatstico.

Estou considerando trabalhar simultaneamente prevalencia e interface externa por webservices e


eventualmente processamento distribudo.

Estou procurando algum que possa me ajudar neste projeto pois no sou especialista em nenhuma
dessas duas tecnologias.

Se algum estiver interessado, por favor entre em contato em a.r.o.f@uol.com.br.


_________________
JavaFree.org
1.
vfpamp
Posts:6098

Publicado em: 09/04/2009 23:18:44

WebServices no so a melhor sada se voc quer velocidade. Entre outras coisas o parse do XML
ainda lentinho...

Que tal RMI diretamente ou EJB?


_________________
Vitor Pamplona
http://vitorpamplona.com
@vitorpamplona
1.
nuba
Posts:2

Publicado em: 09/04/2009 23:18:44

ol, peo desculpas pela minha ignorancia, mas fiz o download do prevayler 2.0 mas no estou
conseguindo instalar o plug-in no Eclipse e nem no Gel, alguem pode me dar uma ajuda como fao
isso?
valeu!

1.
vfpamp
Posts:6098

Publicado em: 09/04/2009 23:18:44

Ol Nuba,

No existe um plugin para download no site do Prevayler. Voc est tentando instalar o Preclipse?
Para fazer o prevayler funcionar s baixar o jar e colocar no classpath da sua aplicao.

[]s
_________________
Opaaa, deu certo aqui hein Vitor, valeu pela ajuda!

Você também pode gostar