quarta-feira, 11 de abril de 2007

Controlando as transações Parte II


Bom, agora que vc ja esta entretido com o controle de transações, nos vamos fazer este controle de forma implicita, isso irá tornar um pouco obscuro a sua percepção sobre o assunto. O controle de transações descrito neste artigo é uma obra de Davi Luan Carneiro, ele escreveu um artigo no GUJ descrevendo passo a passo como esse processo funciona, por isso eu vou descrever aqui apenas a nossa implementação para este tipo de controle de transação.


Este controle de transação se encaixa perfeitamente com o artigo anterior. Criamos novamente uma classe de negocio que será responsavel por fazer o controle de transações, essas classes devem permanecer na camada de "model", assim como descrevemos anteriormente.

|---+model
|
|---+busines
|---+persistence
|---dao
|---dto
|---factory
|---transaction

Creio que vc ja deva saber porque frizei estes packages, porem o package transaction será um pouco mais complexo, pois ira abrigar as classes desenvolvidas pelo Davi. A grande sacada dessa solução é o uso de Annotations, agora ao invés de ficar replicando codigo, nos iremos apenar anotar se tal metodo requer ou nao uma transação, veja o codigo abaixo.

public class LoginBO{
private DAOFactory factory = null;

public LoginBO(){
factory = DAOFactory.getDAOFactory(DAOFactory.HIBERNATE);
}

@HibernateTransaction
public Person makePersistent(Person person) throws RuntimeException {
return factory.getPersonDAO().makePersistent(person);
}
}

Ainda nao acabamos, pois para que esta anotação funcione nos vamos precisar instanciar a nossa classe de negocio através de uma forma um pouco peculiar, portanto vamos esconder isso usando o pattern Factory. Crie a seguinte factory junto de suas classes de negocios.

public class BOFactory {

public static LoginBO getLogin(){
try{
return (LoginBO)TransactionClass.
create(LoginBO.class, HibernateInterceptorAnnotation.class);
}catch (Exception ex){
return null;
}
}
}

Agora se vc quiser gravar um registro no banco de dados, vc deve proceder da seguinte maneira

LoginBO loginBO = BOFactory.getLogin();
Person person = new Person("Ronildo Braga Jr","26-01-1982","M");
loginBO.makePersistent(person);


Eu vou descrever aqui as demais classes que foram adicionadas ao nosso package transaction, porem aconselho vc a ler o artigo do Davi por inteiro.


package org.iprogramming.model.persistence.hibernateTransaction;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Utilizaremos esta anotação para marcar os métodos que
* queremos que sejam transacionais. Consideramos como
* métodos transacionais aqueles cujo processamento
* constitui uma única transação com o banco
* @author Ronildo
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface HibernateTransaction {}




package org.iprogramming.model.persistence.hibernateTransaction;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import org.apache.log4j.Logger;
import org.iprogramming.Util;


/**
* Cerne do componente para controle de transacao. Faz uso de CGLib,
* uma biblioteca que provê mecanismos de manipulação de bytecode, permitindo
* implementar interfaces dinamicamente, interceptar a chamada de métodos.
* Chamando determinado método, interceptamos a sua ação, e verificamos se este método
* é transacional. Se for, abrimos uma transação, e executamos o método.
* Se ele for executado com sucesso, damos commit na operação.
* Porém, se der exceção, fazemos um rollback
*
* Isso se parece com a solução de Filtros Http, porém com uma vantagem:
* o controle transacional não fica misturado com a API do Controller (C do padrão MVC),
* e é mais flexível, pois não se prende ao contexto web
*
* Observe também que esta solução é melhor que tratar as transações diretamente nas classes Java.
* Isso porque você vai evitar muito código repetitivo (try, catch, commit, rollback, etc),
* e não vai “poluir” inúmeras classes com este tipo de código.
* @author Ronildo
*/
public abstract class HibernateInterceptor implements MethodInterceptor {

private static final Logger logger = Util.startLogger(HibernateInterceptor.class);

/**
* O método intercept, proveniente da interface MethodInterceptor (CGLib), se encarrega
* de fazer o controle transacional. Veja que ele usa o HibernateHelper,
* e que o método transacional é explicitamente invocado, através de methodProxy.invokeSuper(),
* e o seu retorno é explicitamente devolvido
* @throws Throwable
*/
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

if (isTransactional(object, method)){
logger.debug("logica de negocio deve ser executada dentro de uma transacao");
HibernateHelper.beginTransaction();
}

Object result = null;
try {
result = methodProxy.invokeSuper(object, args);
HibernateHelper.commitTransaction();
logger.debug("logica de negocio executada com sucesso");
}catch (Throwable e){
logger.debug("erro ao executar logica de negocio");
HibernateHelper.rollbackTransaction();
throw e;
}

return result;
}


/**
* Definido como abstrato para para obter máxima flexibilidade, pois apenas
* estendendo esta classe e implementando este método, podemos saber se o
* método é transacional ou não de diversas maneiras, como arquivos XML,
* arquivos texto, e anotações! (Esta classe é um caso do pattern Template Method).
*/
public abstract boolean isTransactional(Object object, Method method) ;
}




package org.iprogramming.model.persistence.hibernateTransaction;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
* Está é a nossa implementação de HibernateInterceptor. O método isTransactional
* procura no método a anotação @HibernateTransaction. Se encontrar, retorna true,
* indicando que o método é transacional. Se não encontrar, retorna false.
* @author Ronildo
*/
public class HibernateInterceptorAnnotation extends HibernateInterceptor {

public boolean isTransactional(Object object, Method method) {
Annotation annotation = method.getAnnotation(HibernateTransaction.class);
return annotation == null ? false : true;
}
}





package org.iprogramming.model.persistence.hibernateTransaction;

import net.sf.cglib.proxy.Enhancer;

/**
* Para podermos interceptar os nossos métodos usando CGLib, não podemos criar
* suas classes através de um construtor. Devemos criá-las a partir do objeto Enhancer,
* fornecido pela API. Assim, implementamos uma classe para nos ajudar na construção
* de objetos que possuam métodos transacionais.
*
* Esta classe possui o método create, que recebe dois argumentos do tipo Class: o beanClass,
* que se refere à classe que desejamos criar; e o interceptorClass, que se refere ao tipo de Interceptor usado.
* Neste último argumento, passaremos HibernateInterceptorAnnotation.class, mas poderíamos
* também passar HibernateInterceptorXML.class, HibernateInterceptorTextFile.class, enfim,
* qualquer coisa que a sua imaginação permitir.
*
* Esta classe nao deve ser conhecida em vários lugares da aplicação. Procure escondê-la utilizando o
* pattern Factory, ou integrá-la com o seu mecanismo de IoC (como Spring Framework ou PicoContainer).
* Assim, você evita “poluir” suas classes desnecessariamente.
* Bem, em termos práticos: se quisermos que determinada classe possua um método transacional,
* ela deve ser criada por meio de TransactionClass
* @author Ronildo
*
*/
public class TransactionClass {

public static Object create(Class beanClass, Class interceptorClass) throws InstantiationException, IllegalAccessException{
HibernateInterceptor interceptor = (HibernateInterceptor)interceptorClass.newInstance();
Object object = Enhancer.create(beanClass, interceptor);
return object;
}
}


Portanto finalizamos aqui, no proximo artigo irei demonstar soluções usando o SpringFramework e finalmente depois uma solução com EJB.

Controlando as transações Parte I


Este artigo é primeiro artigo sobre controle de transações do hibernate. O controle de transações pode ser algo muito facil ou muito dificil dependendo da abordagem que você queira adotar, por este motivo demonstrarei não somente a minha opção mas também as diversas opções que você pode adotar, após estes artigos espero que vc seja capaz escolher a melhor solução para você.


A primeira opção é relativamente simples, nos vamos criar uma classe de negocio que será responsavel por fazer o controle de transações, e o programador responsavel por escrever essas classes deve saber executar de forma explicita as rotinas de begin transaction, commit e rolback do hibernate. Essas classes devem permanecer na camada de "model", por isso descrevemos abaixo aonde vc deve adicionar tais classes

|---+model
|
|---+busines
|---+persistence
|---dao
|---dto
|---factory
|---transaction

Note que agora eu frizei dois packages(busines e transaction), apesar de nossas classes se encontrarem no package busines, nos iremos usar as classes no package transaction tambem, pois nela se encontra as rotinas do hibernate, os quais a propria documentacao do hibernate disponibiliza. Lembre-se que nossos packages é divido por funcionalidades, e por isso as classes de busines não estao contidas no package de persistence.


Abaixo segue uma solução que vc pode usar para controlar as suas transacoes do hibernate, quando eu disse que vc devia executar de forma explicita as rotinas de begin transaction, commit e rolback do hibernate, eu quis dizer exatamente isso: HibernateHelper.beginTransaction();. A classe HibernateHelper será descrita posteriormente.

public class LoginBO{
private DAOFactory factory = null;

public LoginBO(){
factory = DAOFactory.getDAOFactory(DAOFactory.HIBERNATE);
}

public Person makePersistent(Person person) throws RuntimeException {

try {
HibernateHelper.beginTransaction();
person = factory.getPersonDAO().makePersistent(person);
HibernateHelper.commitTransaction();
}catch (RuntimeException e){
HibernateHelper.rollbackTransaction();
throw e;
}
return person;
}
}

As funcoes ou metodos da nossa classe de negocio poderão lançar uma RumtimeException, pois a ideia aqui é simples: A nossa classe deve fazer o controle de transacoes e tratar qualquer erro da camada de persistencia, e para isso nos executamos rolback para tratar a exceção, porem nos lançamos novamente a exceção para avisar a camada acima que ocorreu algum erro, mas que nao precisa se preocupar em resolver, pois gerenciar o banco de dados é nossa responsabilidade.


Agora se vc quiser gravar um registro no banco de dados, vc deve proceder da seguinte maneira

LoginBO loginBO = new LoginBO();
Person person = new Person("Ronildo Braga Jr","26-01-1982","M");
loginBO.makePersistent(person);


Abaixo exibimos a classe HibernateHelper, como dito anteriormente, a intenção aqui não é ficar replicando os materiais da internet. Basta dizer que esta classe deve: Gerenciar os objetos Session e Transaction, bem como deverá ser usada na confecção dos DAOs (Data Access Object). Ela faz uso de ThreadLocal, garantindo que cada thread possua uma única instância de Session e Transaction, e protegendo esses objetos de qualquer problema de concorrência

public class HibernateHelper {

private static final SessionFactory sessionFactory;
private static final ThreadLocal sessionThread = new ThreadLocal();
private static final ThreadLocal transactionThread = new ThreadLocal();

static {
try {
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
//Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}

public static Session currentSession() {
if (sessionThread.get() == null) {
Session session = sessionFactory.openSession();
sessionThread.set(session);
}
return (Session) sessionThread.get();
}

private static void closeSession() {
Session session = (Session) sessionThread.get();
if (session != null)
session.close();

sessionThread.set(null);
}

public static void beginTransaction() {
if (transactionThread.get() == null){
Transaction transaction = currentSession().beginTransaction();
transactionThread.set(transaction);
}
}

public static void commitTransaction() {
Transaction transaction = (Transaction) transactionThread.get();
if (transaction != null && !transaction.wasCommitted() && !transaction.wasRolledBack()) {
transaction.commit();
transactionThread.set(null);
}

closeSession();
}

public static void rollbackTransaction() {
Transaction transaction = (Transaction) transactionThread.get();
if (transaction != null && !transaction.wasCommitted() && !transaction.wasRolledBack()) {
transaction.rollback();
transactionThread.set(null);
}

closeSession();
}
}


Portanto finalizamos aqui, no proximo artigo iremos fazer o controle de transação de forma implicita, ou seja, nao iremos ficar replicando muito codigo. A solução acima é bem pratica e funcional, porem é um pouco tedioso ficar toda hora executando begin transaction, comit e etc



quinta-feira, 5 de abril de 2007

A Fabrica de DAOs


Este artigo explora as classes envolvidas na fabrica de DAOs do ITrust, nossa fabrica encontra-se dentro do package "org.iprogramming.model.persistence.factory". A fabrica de DAOs tem a funcão de abstrair qual a forma de acesso ao banco de dados e setar a sessão corrente do hibernate. Apesar de nosso foco ser a integração com o hibernate, nao podemos ficar presos a esta ferramenta, entao vamos dar a possibilidade de vc acessar o banco de dados via JDBC. Segue abaixo nosso exemplo

|---+persistence
|
|---dao
|---dto
|---factory
|---transaction


public abstract class DAOFactory {
public static final int HIBERNATE = 1;
public static final int SQLServer = 2;

public static DAOFactory getDAOFactory(int whichFactory){
switch(whichFactory){
case 1:
return new HibernateDAOFactory();
case 2:
return new SQLDAOFactory();
default:
return null;
}
}

public abstract LoginDAO getLoginDAO();
}


Essa é a nossa implementação para uma fabrica de DAOs do Hibernate

public class HibernateDAOFactory extends DAOFactory{
private static Session getCurrentSession() {
return HibernateHelper.currentSession();
}

public LoginDAO getLoginDAO() {
return new HibernateLoginDAO().setSession(getCurrentSession());
}
}

Ao instancia o nosso DAO, precisamos setar a sessão corrente do hibernate, isso é feito através do método que herdamos da classe GenericHibernateDAO. Portanto finalizamos aqui, agora se vc precisa consultar os registros da tabela de login basta vc fazer o seguinte procedimento:

DAOFactory factory = DAOFactory.getDAOFactory(DAOFactory.HIBERNATE);
LoginDAO loginDAO = factory.getLoginDAO();
List list = loginDAO.list(Login.class);

No próximo artigo vamos estudar como fazer o controle de transações do hibernate.

Data Access Object Generic


Esse artigo explora as classes envolvidas no DAO do ITrust. O DAO que iremos usar é implementado com Hibernate e JDK5, muita gente acha desnecessário implementar DAO com Hibernate, portanto mostramos aqui o porque dessa implementação. O DAO do ITrust encontra-se dentro do package org.iprogramming.model.persistence.dao e nele encontramos as sepaçoes de packages descritas abaixo

|---+dao
| |
| |---generic
| |---hibernate

Dentro do package dao nos iremos adicionar todas as nossas interfaces de DAO, estas interfaces irão abstrair qual a forma de acesso ao banco de dados e serve para especificar quais os metodos padrões que um DAO deve possuir. Porem todos os DAOs vão possuir metodos semelhantes no caso do hibernate, sendo assim, iremos criar primeiro um GenericDAO para pouparmos um certo trabalho, portanto a interface GenericDAO sera o nosso exemplo e ainda terá dupla funcionalidade descrita posteriormente

public interface GenericDAO <T, ID extends Serializable>{
public T findById(Class clazz, ID id);
public List list(Class clazz);
public List list(Class clazz, int firstResult, int maxResults);
public List listByExample(T entity);
public T makePersistent(T entity);
public void makeTransient(T entity);
}

Devemos observar que esta interface será implementada em todas as demais interfaces, e isso so foi possivel através do recurso Generic implementado no JDK5, porem cada DAO possui as suas peculiaridades, e para criarmos as peculiaridades de cada DAO nos vamos simplismente criar nossos DAOs extendendo a GenericDAO e adicionando os metodos peculiares, segue exemplo abaixo.

interface LoginDAO extends GenericDAO<Login, Long>{
public Login findLoginByNamedQuery(Login arg);
}

Note que ao extendermos a interface GenericDAO nos precisamos especificar os tipo genericos atribuidos a GenericDAO, para vc entender melhor imagine que no lugar T e ID será substituido por Login e Long. Depois nos criamos um metodo especifico para o DAO Login, sendo assim, nao precisamos ficar escrevendo os metodos padroes como insert, delete, update e list.


Agora que ja possuimos a nossa interface para o DAO de Login nos precismos de fato criar uma classe que implementa esta interface, porem agora vamos descrever algo muito peculiar do hibernate. Nos vamos criar um GenericHibernateDAO para abastrair os metodos de insert, delete, update e list, isso tambem é possivel usando o recurso de Generic do jdk5. Segue abaixo o nosso exemplo:

public class GenericHibernateDAO <T, ID extends Serializable, DAOImpl extends GenericDAO<T, ID>> implements GenericDAO<T, ID> {
private Session session;

public DAOImpl setSession(Session s) {
this.session = s;
return (DAOImpl)this;
}

protected Session getSession() {
if (session == null)
throw new IllegalStateException("Session has not been set on DAO before usage");
return session;
}

public T findById(Class clazz, ID id) {
return (T)getSession().get(clazz, id);
}

public List list(Class clazz) {
return getSession().createCriteria(clazz).list();
}

public List list(Class clazz, int firstResult, int maxResults) {
Criteria criteria = getSession().createCriteria(clazz);
criteria.setFirstResult(firstResult);
criteria.setMaxResults(maxResults);
return criteria.list();
}

public List listByExample(T entity) {
Criteria criteria = getSession().createCriteria(entity.getClass());
Example sample = Example.create(entity);
sample.enableLike();
sample.excludeZeroes();
criteria.add(sample);
return criteria.list();
}

public T makePersistent(T entity) {
getSession().saveOrUpdate(entity);
return entity;
}

public void makeTransient(T entity) {
getSession().delete(entity);
}
}

A classe GenericHibernateDAO é o cerne de todos os nossos DAOs, pois este ira conter todas as rotinas basicas para as nossas tabelas no banco de dados. Ainda podemos perceber a segunda funcionalidade da Inteface GenericDAO, pois agora a interface esta sendo implementada ao inves de extendida. Não perca tempo imaginando o que é isso <T, ID extends Serializable, DAOImpl extends GenericDAO<T, ID>> implements GenericDAO<T, ID> Apenais saiba que o conceito aqui é o mesmo descrito para a interface GenericDAO, ou seja, isto são tipos genericos que serão especificados quando alguem extender essa classe


Agora vc deve entender o uso do Generics em nossos DAOs, pois ao extender a classe GenericHibernateDAO nos especificamos quais sao os atributos que a classe 'Pai' deve usar. Note que nao precisamos escrever as demais rotinas de insert, delete, update e list. Agora tente implementar outro DAO e vc irá perceber que vc so precisar criar algumas classes e extender outras, se vc ja criou DAOs usando JDBC vc irá entender porque o hibernate é uma ótima ferramenta.

public class HibernateLoginDAO extends GenericHibernateDAO<Login, Long, LoginDAO> implements LoginDAO {
public Login findLoginByNamedQuery(Login arg)
Query select = getSession().getNamedQuery("findUser");
select.setLong("pkUsers", arg.getPkLogin());
select.setString("roleName", arg.getRoles().iterator().next().getName());

List<Login> logins = (List<Login>) select.list();
for(Login login : logins)
return login;

return null;
}
}


Terminamos aqui os nossos DAOs, veja abaixo o UML e estude, pois no proximo artigo vamos descrever como vc deve criar as instancia de seus DAOs e como controlar as transacoes do hibernate, provavelmente vc deve estar se perguntando: O que sao os metodos setSession e getSession na classe GenericHibernateDAO. Esses metodos serão descritos no proximo artigo.


quarta-feira, 4 de abril de 2007

O Inicio


O ITrust é o inicio de um ERP open source, com cadastro de clientes, contas a pagar e etc. Este é o primeiro artigo de uma série, descrevendo a aplicação dos patterns envolvidos e bibliotecas do projeto. O conteudo dos arquivos encontra-se no source forge em https://sourceforge.net/projects/itrust.


Vamos iniciar o sistema descrevendo a hierarquia de pastas do projeto.

--+ITrust
|
|--+src
| |
| |---+org.iprogramming
| |
| |---+controller
| |---+model
| |---+view
|--+web
|
|---+css
|---+images
|---+include
|---+js
|---+pages
|---+WEB-INF

Podemos ver que as pastas são bem intuitivas e ao decorrer dos artigos vamos explorar o conteudo de cada pasta. Eu presumo que vc ja saiba criar um projeto na sua IDE de preferencia e criar esta hierarquia de pastas. Portanto vamos comecar adicionando as bibliotecas do projeto, eu uso as seguintes: Hibernate, JSF, Ajax4JSF, Tomahawk. Estas são as bibliotecas principais, porem iremos adicionar muitas outras para dar suporte a estas. Portanto baixe as bibliotecas e adicione estas ao seu projeto, caso vc tenha problemas em achar todas as bibliotecas envolvidas vá ao site do projeto no source forge e veja em detalhes as bibliotecas usadas.


Agora que ja temos o nosso projeto criado, vamos começar explorando as classes no package model, nele vamos encontar todas as classes de persistencia, acesso ao banco de dados e logica de negocio. A divisão de 'packages' usadas nesse projeto não é obrigatoria, porem voces vão perceber que eu costumo separar as classes em seus devidos packages caracterizados por funcionalidades. Vejamos abaixo uma breve descrição dos packages contidos no model.

model
|
|
|---busines
|--+persistence
|
|---+dao
| |
| |---generic
| |---hibernate
|
|---dto
|---factory
|---transaction

model --------> Contem todos os packages resposaveis pelo modelo do distema
busines ------> Representa as classes de logica de negocio do sistema
persistence --> Contem todos os packages envolvidos ao banco de dados
dao ----------> Representa as interfaces de nossos Data Access Object(DAO)
generic ------> Representa as classes e as interfaces genericas para dar suporte ao nossos DAOs
hibernate ----> Representa as classes de persistencia no banco de dados
dto ----------> Representa as classes referente aos registros no banco de dados
factory ------> Representa as classes para criar instancia de nossos DAOs
transaction --> Representa as classes para controle de transações do hibernate



Vamos iniciar explorando as classes do package dto, aqui devemos criar as classes que deverão representar os registros no banco de dados do nosso ERP. Vamos descrever cada tabela, porem vamos começar com tres tabelas basicas Company, Person e Login. Essas tabelas podem ser criadas usando a seguinte sintaxe para um banco de dados postgres

create sequence seq_company;
CREATE TABLE company
(
pk_company bigint NOT NULL DEFAULT nextval('seq_company'::regclass),
name character varying(45) NOT NULL,
description text,
CONSTRAINT ctr_company PRIMARY KEY (pk_company)
);

create sequence seq_person;
CREATE TABLE person
(
pk_person bigint NOT NULL DEFAULT nextval('seq_person'::regclass),
fk_company bigint NOT NULL,
name character varying(45) NOT NULL,
born date,
description text,
CONSTRAINT ctr_person PRIMARY KEY (pk_person),
CONSTRAINT ctr_company_in_person FOREIGN KEY (fk_company)
REFERENCES company (pk_company) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
);

create sequence seq_login;
CREATE TABLE "login"
(
pk_login bigint NOT NULL DEFAULT nextval('seq_login'::regclass),
fk_person bigint NOT NULL,
"login" character varying(10) NOT NULL,
"password" character varying(10) NOT NULL,
description text,
CONSTRAINT ctr_login PRIMARY KEY (pk_login),
CONSTRAINT ctr_person_in_login FOREIGN KEY (fk_person)
REFERENCES person (pk_person) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
);

Essas tabelas serão respresentadas no nosso package DTO da seguinte maneira:

public class Company implements java.io.Serializable {
//Non Fields
public boolean marked = false;
// Fields
private long pkCompany;
private String name;
private String description;
private Set<Person> persons = new HashSet<Person>(0);

//...geters and seters
}

Creio que a representação do DTO company descrito acima ja seja suficiente para que vc possa criar sozinho os demais DTO.
Existe algo fora do padrão no nosso DTO, isso é devido ao atributo marked. Esse atributo que nao existe na tabela será explorado posteriormente quando estudarmos a camada de apresentação feita em JSF. Agora que ja possuimos as nossas tabelas no banco de dados e nosso DTO, precisamos entao configurar o hibernate. Será necessário que vc crie o arquivo Company.hbm.xml, segue abaixo exemplo

<hibernate-mapping>
<class name="org.iprogramming.model.persistence.dto.Company" table="company" schema="public">
<id name="pkCompany" type="long">
<column name="pk_company" />
<generator class="sequence">
<param name="sequence">seq_company</param>
</generator>
</id>
<property name="name" type="string">
<column name="name" length="45" not-null="true" />
</property>
<property name="description" type="string">
<column name="description" />
</property>
<set name="persons" inverse="true">
<key>
<column name="fk_company" not-null="true" />
</key>
<one-to-many class="br.com.verano.model.persistence.dto.Person" />
</set>
</class>
</hibernate-mapping>

Ok, mapeamos no hibernate como funciona a nossa tabela Company. Lembre-se que estamos explorando o package DTO, portanto o arquivo Company.java e Company.hbm.xml encontra-se no package dto. Agora devemos configurar o hibernate de fato, e para isso ja existe dezenas de materiais, portanto aconselho que leia os tutorias na pasta de documentação do projeto no source forge. Não quero ficar replicando aqui os tutoriais ja existentes, o GUJ possui uma serie de artigos sobre hibernate e eu adicionei eles na pasta de documentacao do projeto, portanto eu aconselho que leia os tutorias pois no proximo artigo vamos presumir que vc ja saiba no minimo fazer uma consulta usando hibernate.


Esse foi nosso primeiro pattern abordado, o pattern DTO. O conceito descrito sobre esse pattern é relativamente simples e creio que vc nao teve muitos problemas para entender. No proximo artigo vamos explorar o Pattern DAO com hibernate e as coisas vão se tornar mais complexas