Mostrando postagens com marcador hibernate. Mostrar todas as postagens
Mostrando postagens com marcador hibernate. Mostrar todas as postagens

22 de mai. de 2009

RMI e HIbernate... lições aprendidas


Estou participando de um projeto onde decidimos utilizar RMI para conversação de dois módulos do sistema. A decisão não vem ao caso agora, mas achei interessante gurdas alguns "causos"...


RMI e Hibernate, onde tudo começou


Como falei anteriormente, decidimos utilizar RMI para integrar dois módulos do sistema. Um módulo responsável pela parte de negócio( persistência também) e outro por uma parte específica bem baixo nível (baixo nível = bytes.. 01010101...etc...).

Então, o gênio projetista teve a seguinte idéia: "Vamos utilizar as classes persistentes para trafegar via RMI".

Resultado: LazyInitializationException -LIE.


Em um determinado método de uma classe acessada via RMI o retorno era um objeto que foi buscado do Hibernate. Este objeto tinha outros objetos, que tinham outros objetos, que tinham outros objetos... blá blá blá...

Soluções:


1º) Colocar "transient"(do java não do JPA) nos atributos que não deveriam trafegar via RMI. Puramor de Deus, Nãããão!!!

Imagina ficar colocando transiente em tudo que é atributo espalhado pelo código inteiro. Loucura!!!

2º) Modificar o design
Interessante... muito interessante...
O Design... (não é de moda porr!!)


Tentei fazer algo que representasse o problema. Então abaixo estão algumas classes de domínio, mapeadas no hibernate.


OBS: Para quem não sabe, em RMI devem existir interfaces comuns nos dois lados da comunicação. Então a interface PessoaData é conhecida pelos dois módulos.


Agora, viram o que o projetista gênio fez ?!?!?!

A classe Pessoa implementa a interface PessoaData. Na imagem acima temos somente um exemplo, mas no contexto real são umas 20 classes que irão trafegar via RMI. Todas essas classes são entidades persistentes.

Observe que a interface PessoaData retorna byte[]. Isso mesmo.. o "carinha" que utiliza estas classes vai precisar dos dados convertidos em bytes. Guarde esta informação.


Confesso que o projetista gênio(agora já deve-se saber quem é o projetista... :D ) percebeu a burrada somente quando ocorreu o erro com hibernate.


O que vocês conseguem enchergar ai?

Bom, vou dizer o que eu consegui enxergar:

  • Uma classe persistente implementa uma interface utilizada para comunicação entre sistemas. Acomplamento! Entidade persistente conhece uma interface onde o objetivo é comunicação de dados entre sistemas... "nada a vê"
  • Pelo motivo acima, a entidade persistente é responsável por converter String, Integer, Date em bytes. Coesão! Tava tudo misturado, conversões com bytes em uma classe onde o objeto é enviar e obter informações do banco de dados.

Solução tomada

Utilizamos os famosos Transfer Objects. Segue o exemplo:




Matamos o problema de coesão, onde a classe PessoaTo é responsável por trabalhar os dados para comunicação.
Matamos o problema de acomplamento onde a classe Pessoa não sabe que a classe PessoaTo existe.
Matamos o LazyInitializationException. A classe TO contém apenas o que será necessário para transferência.

Lições aprendidas
  • Colocar tudo em uma classe é diferente de economizar tempo
  • Preguisoço trabalha em dobro... :D
  • Projetos iterativos minimizam os erros. Descobrimos o problema no início e retrabalho foi de aproximadamente 5hs.
  • Enviar objetos utilizados para persistência via RMI-> ... LazyInitializationException
  • Spring RMI exporter facilita muito!
  • Cuidar as dependências das classes

Era isso..

Abraço!

24 de set. de 2007

Criar uma aplicação com hibernate

Dae gurizada!!!

Esse é um post simples para quem quer confirguar uma aplicação para usar Hibernate com Annotations.

Eu usei o
Netbeans 5.5 para montar esse exemplo. Será necessário fazer o download do Hibernate Annotations, que por sua vez precisa do Hibernate Core. Para os teste utilizei o Postgresql 8.2. Segue os links: Abaixo está o link da aplicação exemplo: E só clicar nos links que irá direto para o local onde pode ser veito o download.


1º Passo: Criar o projeto

Esse artigo ainda foi feito no NetBeans 5.5. Para criar um novo projeto vá em Arquivo -> Novo Projeto. Selecione a categoria "Geral" e clique em Aplicação Java. Chamei o projeto de HibernateApp.

Crie uma pasta chamada de "lib" na raiz do seu projeto. A estrutura de diretórios vai ficar assim:


Criado o nosso projeto já criei alguns pacotes e classes. Veja:




Agora temos qu adicionar os jar necessários para a aplicação rodar. Se você notar, o hibernate tem um monte de JARs, mas nem todos são obrigatórios.

Abaixo estão quais os JARs devem estar na pasta LIB do nosso projeto. Vou separar os jars do Hibernate Core e do Hibernate Annotations, mas todos devem ser colocados na pasta LIB direto, não em subpastas.

Hibernate Core - 3.2.5GA:
  • antlr.jar
  • cglib.jar
  • asm.jar
  • asm-attrs.jars
  • commons-collections.jar
  • commons-logging.jar
  • hibernate3.jar
  • jta.jar
  • dom4j.jar
  • log4j.jar

Hibernate Annotations 3.3.0GA
  • ejb3-persistence
  • hibernate-commons-annotations
  • hibernate-annotations
Postgresql 8.2
  • postgresql-8.2-505.jdbc4

A minha pasta lib ficou assim:



Com os JARs na pasta lib ainda temos que adicionar ao projeto pelo Netbeans.
Para isso clique com o botão direito no nome do projeto e clieque em propriedades:


Depois clique em "Bibliotecas" e no botão "Adicionar Jar/Pasta" e localize os jars na pasta lib do nosso projeto:



2º Passo: Criar as classes - Entidades Persistentes.
É considerado "Entidade persistente" as classes que serão inseridas no banco de dados.

No nosso exemplo tenho duas classes que serão persistidas no banco de dados. A classe Pessoa e Endereco.

Veja com elas ficaram:

Explicação

@
Entity: Toda classe persistente (POJO) deve user @Entity. Isso indica que a classe é uma entidade persistente(Entity Bean). Ou seja, existe uma tabela no banco de dados que representa essa classe. Por padrão o hibernate considera o nome da tabela igual ao nome da classe.

Caso sua classe possua um nome diferente ao nome da tabela, é necessário usar a anotaçao a seguir:


@
Table:
essa anotação é utiliza quando informamos o nome da tabela. Veja a classe Pessoa. O nome da classe é Pessoa, mas o nome da tabela no banco é TB_Pessoa.

@Id
:
Para o hibernate o ID é a forma de identificar o objeto (bem óbvio).
Os ID's podem ser gerados de várias formas dependendo do banco utilizado. O Postgresql, por exemplo, utiliza sequences. O MySQL tem um campo autoincrement e assim por diante.

Existem vários tipos de "generators". Veja esse link ou veja o meu outro post.


@
Column:
Essa anotação simplesmente indica qual coluna da tabela a propriedade irá referenciar. Por padrão todos os atributos da classe são pripriedades de tabelas.

@
ManyToOne:
esse atributo faz as relações entre as classes.

@
JoinColumn:
essa anotação indica qual coluna da classe Pessoa referencia a classe Endereço.

Agora um desenho para melhorar a compreensão:



3º Passo: Classe/Arquivo de configuração:

Você deve estar se perguntando:

- Por que esse retardado colocou "'classe/arquivo de configuração" ?

Simples! Existem as duas formas de configurar o hibernate. Na verdade são 3.. heheheh

hibernate.cfg.xml ou hibernate.properties: Até chegar o annotations e jpa o hibernate era configurado através de um arquivo xml ou .properties. Neste arquivo estão as informaões de conexão com o banco e as classes que serão mapeadas. Utiliza-se esse arquivo quando vamos utilizar somente o Hibernate Core.
persistence.xml: A especificação EJB3 definiu o arquivo padrão para configuração do mapemaneto objeto relacional. Este arquivo é semelhanto ao hibernate.cfg.xml ( e tambem foi baseado nele). Utiliza-se esse arquivo quando vamos utilizar o EntityManager.
Configuração programática (classe): Uma alternativa ao antigo hibernate.cfg.xml. Todas as configurações informadas no arquivo de configuração do hibernate, podem ser setadas em tempo de execução.

Nosso hibernate.cfg.xml

Vamos ver primeiro o arquivo de configuração.

Crie um arquivo "hibernate.cfg.xml" dentro da pasta src do seu projeto.

OBS inútil: esse arquivo do hibernate pode ter outro nome. É obrigatório o arquivo conter "cfg.xml".
Ex: "qualauernome.cfg.xml"
Mas o nome mais comum é "hibernate.cfg.xml".
Veja como fica o meu projeto no netbeans:


Criado o arquivo vamos ver a maldita configuração:
Explicação
connection.driver_class: Nome da classe do driver que será utilizado. No meu caso estou utilizando o postgresql.

connection.url: URL para conexão com o banco. connection.username: nome do usuário para conexão com o banco connection.password: senha para conexão com o banco
Até aqui são configuraçoes normais que você já deve ter usado para criar conexões com o banco via JDBC dirto.

connection.pool_size
: Configuração do pool de conexão. No nosso caso o hibernate manterá sempre 1 conexão com o banco.

dialect (Importantíssimo): O hibernate gera o sql dinamicamente de acordo com o banco de dados utilizado. A forma do Hibernate saber para qual banco gerar o SQL é o "dialect". Veja aqui a tabela de "dialetos" do hibernate.
cache.provider_class: O hibernate possui um podero sistema de Cahce de objetos. Eu particularmente nunca utilizei. Se alguem quiser se aprofundar veja em:
show_sql: Com o valor "true" exibe todos os comandos SQL executados pelo hibernate no console da IDE e no arquivo de LOG, caso configurado.
Ótimo para achar erros.

hbm2ddl.auto(maravilhoso): Essa cara aqui é muito bom. Esta ferramenta do hibernate gera o schema para o banco de dados, ou seja, ele cria o banco de dados com os seus relacionados, chaves primárias, etc.. a partir das classes configuradas no hibernate. Essa ferramente é executado quando criamos o SessionFactory que veremos a seguir.

Algums valores:
create-drop: Cria as tabelas do banco quando o SessionFactory é iniciado e deleta a base de dados quao termina a executação. Muito cuidado ao usar essa configração com o banco de dados de produção..hehehehe

update
: Atualizar colunas e tabelas do banco de dados. Essa configuração não deleta nenuma coluna, somente insere.
OBS: É necessário já estar criado o "database".


"mapping class"
:
Bom esse trecho não é bem uma configuração. Aqui estamos adicionando as classes que serão mapeadas no hibernate. Todas as classe que iremos mapear no hibernate tem que ser adicionadas na configuração.


Agora que foi entendido a configuração do hibernate vamos ver como fazer essa mesma configuração na classe:



Nessa classe criamos uma instância da classe AnnotationConfiguration que é a classe do hibernate que recebe configurações iguais ao do XML.

Veja que chamei o método "setProperty" para setar as propriedades.


4º Passo: Iniciar o Hibernate.

Eu criei uma classe chamda Hibernate
Config com os métodos iniciarHibernateClasse(mostrado acima) e iniciarHibernateXML, abaixo.
A lógica para istânciar um objeto SessionFactory é a mesma com o arquivo de configuação e para a classe.

Criar o objto AnnotationConfiguration

Setar as configurações.
Classe: setar as configurações a partir do método
setProperty

Arquivo cfg.xml: chamar o método configure() da classe AnnotationConfiguration. Este método irá carregar as configurações do arquivo e retornar um objeto do tipo Configuration.

Chamar o método
Classe: chamar o método "buildSessionFactory()" da classe AnnotationConfiguration.
Arquivo: chamar o método "buildSessionFactory()" do objeto retornado do método "configure()"


Se ficiu confuso esses passos veja a classe que vai ajudar.


Bom.. mais uma vez fica aqui meu pedido de críticas e sugestões...

No mais era isso...

Abração!




26 de ago. de 2007

O que é o hibernate ?





Hibernate. É bem simples entender pra que serve esse bicho: Mapeamento Objeto Relacional

Para os mais experientes falar que o Hibernate faz a "ponte" entre o conceito Relacional com o Orientado a Objetos é fácil. Mas tem bastante gente que não cosegue enxergar isso.


Agora veja da seguinte forma. Temos uma tabela, o exemplo clássico, "Pessoa"
Bom ai temos uma tablea com 3 colunas. Transformar isso em objeto é fácil.
Seria um objeto da seguinte forma: Difícil fazer o "Mapemaneto Objeto Relacional" ??

Agora imagine este relacionamento:
Por favor, ignore o fato de ter feito um ER em uma ferramento de UML... :D
Você consegue enxergar que uma pessoa tem um carro e um endereço?? E que este carro tem um modelo ?? Transformar issto em objeto ainda continua fácil.

Mas você já imaginou o código necessário para passar estes dados para objetos ?!

Veja:





















Muitos vão olhar o código e dizer "Isso não é difícil" ou "Isto eu faço!". Realmente não é nada de outro mundo.
Mas imagine um projeto grande, com mais de 800 entidades persistentes. Qualquer programador fiacaria louco !!!



Agora veja o mesmo código com Hibernate:













O quê?! É isso mesmo ??? Sim!!

Claro, tem uma pequena parte que não esta neste código. A configuração do hibernate. Mas as consultas são simples assim.

O que eu mostrei até aqui é uma parte do que o Hibernate faz, agora vou fazer um apêndice sobre JPA.


Java Persistence API - JPA

"Java Persistence API é a interface padrão para mapeamento objeto/relacional e gerenciamento de persistência da plataforma Java EE 5.0"

Bom, espero q agora o termo "mapeamento objeto relacional" seja claro para todo mundo.

JPA define um comportamento, um contrato, de como deve ser o mapeamento objeto relacional e o gerenciamento de persistência de objetos java. Veja bem:
define um contrato. A implementação pode ser feita por qualquer um.

Eu li no blog Beyond Click uma comparação perfeita. JPA está para persistência assim como JDBC está para conexão com banco de dados.

As mais famosas implementações JPA são Hibenate e TopLink, existem outras.


Voltando ao hibernate... algumas de suas funcionalidades:

Persistência transparente
Não é necessário executar os comandos SQL de Insert, Update e Delete. O hibernate executa os médoto "save(Object obj)" , "update(Object obj)" e "delete(Object obj)".
Ou seja, ele salva, atualiza ou deleta objetos.

Consulta Fácil
O hibernate possui uma lingugem própria de consulta, o HQL. Esta linguamgem é equivalente a um SQL orientado a objetos. Facilita muuuiiiiiiiiitttoooo as consultas de objetos.

Cache de objetos
O hibernate, se for configurado para isso, trabalha com Cache de objetos.
Se um usuário consultou os dados da pessoa ID 1 no banco. Essa consulta fica em memória. Caso outro usuário consulte os dados da pessoa ID 1 o hibernate retorna os valores do Cache, não realizando uma nova consulta na base.
O isso significa um ganho de desempenho para aplicações de grande porte.

Existem outras!!


Como ele faz isso??
Essa parte que é interessante. O hibernate faz um mapemaneto entre classes java e tabelas no banco de dados.

Veja:

Classe Pessoa















Arquivo de Configuração da classe Pessoa


Esse arquivo xml realiza o tal Mapeamento. É nesse arquivo que esta toda a informação do objeto que será persistido ( inserido no banco de dados).

Este arquivo esta nos dizendo que o objeto Pessoa será inserido na tabela Pessoa. Que o atributo nome, da classe pessoa, representa a coluna nome na tabela Pessoa, e assim por diante.

Esse arquivo XML existe para cada Entidade Persistente. Uma entidade persistente é um objeto que será inserido no banco de dados.


Estrutura do Hibernate
Abaixo está uma foto que tirei so site do hibernate de como é a sua estrutura.




Entity Manager
EntityManager também faz parte da JPA. Esse pacote contem implementações do gerencimaneto de persistência, ciclo de vida dos objetos, a Java Persistence Quary Language e as configurações.
É um JAR com classes que fazem isso escrito ai em cima....hehehe

Hibernate Core

Este o núcleo do hibernate. Imagine o Hibernate Core como o Java SE da paltaforma Java. São os recursos básicos do hibernate, utilzido pelas demais API's.

Hibernate Annotations
O hibernate, como qualquer outro framework para mapeamento objeto relacional, precisa de informarções (chamdados de "meta dados") para transformar tabelas relacionais de uma base de dados em
objetos.
Antes de lançar o Java 5.0, com o recurso de Annotations, esses "meta dados" eram informados em arquivos XML, com o Java 5.0, o XML foi substituído por "annotatinos". Que fazem o mesmo papel do XML, só que agora na prória Classe.
O Hibernate Annotations extende as Annotações padrão da JPA.


É bom saber que o hibernate com XML ainda é muito utilizado.



Espero que quem não conhecia o hibernate possa ter entendido o que o hibernate é.


No decorrer dos próximos argitos irei aprofundar alguns dos assutnos que escrevi aqui.


Abraço!

fui...

Hibernate - da teoria à prática

Dae gurizada!!

Bom, faz tempo que não paro para escrever algo de útil. Tenho um monte de "artigos rascunhos" no meu blog que nunca ternimo.

Hoje, domingo chuvoso, estava assintindo nada na tv e resolvi escrever uma série de artigos sobre o Hibernate, framework que sou apaixonado! E também sobre JPA.

Esse artigos irão abordar os seguintes tópicos:

  • O que é o hibernate ? Introdução ao objetivo do framework hibernate, conceito de mapeamento objeto-relacional e exemplos comparativos entre aplicações utilizando hibernate X JDBC "na mão".
  • Aplicação exemplo 1.Aplicação onde vamos criar relacionamentos simples (one-to-many) e criar algumas telas CRUD.
  • Aplicação exemplo 2. Aplicação onde serão realizadas consultas utilizando a API Criteria, Fetching Lazy ( consultas preguisosas) e relacionamentos many-to-many.
  • Aplicação exemplo 3. Aqui ja teremos um conceito básico e sólido sobre como utilizar o hibernate. Vamos trabalhar com consultas agregadas.

Acredito que para aprender deve-se sempre optar pela prática. Então resovli fazer artigos simples, mas com aplicações.

Espero que seja de ajuda para quem é iniciante.

No mais era isso..

Assim que o primeiro artigo estiver pronto, será liberado.

fui!


19 de mar. de 2007

JPA/Hibernate com Postgresql








Utilizo hibernate com postgresql há alguns anos. Uma dificuldade que sempre tive nas ferramentas para geração dos antigos XML’s e, agora, as classes anotadas é a sequence.

Nenhuma ferramenta que utilizei até hoje trouxe solução para isso.
O resultado disso é alterar o tipo do id.

Sendo assim segue exemplo do XML e de um classe anotada utilizando as sequences do postgres.

No postgres foi criada a seguinte tabela:










PESSOA

id serial

nome varchar(50)

SEQUENCE
pessoa_id_seq


Na aplicação a seguinte classe:









Exemplo do mapemento desta classe com XML:










Exemplo do mapemento com ANNOTATIONS:








No hibernate toda classe persistente deve ter o atributo id, que será utilizado para garantir a integridade dos objetos.

Esse id pode ser gerado de diversas formas, exemplo:

  • sequence
  • native
  • increment
  • identity
  • native

Para obter os detalhes desses tipos de geradores de id, acesse o site do
Hibernate

No exemplo acima utilizamos a sequence. o parâmetro generator, utilizado no XML e com Annotations identifica qual será o gerador do id que o hibernate deverá utilizar., mas para isso é necessário informar o nome da sequence que será utilizada para a respectiva classe.

Espero ter ajudado de alguma forma.

Abraço à todos!