Você está na página 1de 7

1 of 7

Login Registre-se

HOME NOTÍCIAS ARTIGOS FÓRUM WIKI BUSCA SOBRE ENVIAR NOTÍCIA CONTRIBUIR O QUE É JAVA?

Home > Artigos > Frameworks, APIs, Instalação e Configuração >

Hibernate 3 com Spring e DAO Generico


Publicado por dchohfi em 21/09/2009 - 50.726 visualizações

comentários: 0

Bom, galera como prometido neste post irei continuar o tópico anterior adicionando o suporte ao Hibernate em nosso WebService. O Hibernate é um Framework
poderoso de mapeamento objeto-relacional muito conhecido e utilizado, não pretendo entrar em detalhes sobre como configurar o Hibernate nem como mapear seus
objetos para acessar o banco, porém, caso tenha dúvidas acesse este tutorial que mostra como tirar proveito deste Framework e caso tenha alguma dúvida deixe um
comentário ou envie um email que tentarei ajudar.

O Spring possui um módulo para acesso a banco de dados extremamente robusto, podemos fazer controle de transações via AOP, cache, gerenciar pool de conexões
diretamente no contexto do Spring sem se preocupar com qual tecnologia que está implementada e caso seja necessário podemos trocar o modo de acesso sem
precisar modificar todo o projeto, nos dando assim maior mobilidade e escalabilidade. O Hibernate porém não é o único Framework que o Spring provê integração, o
Spring se integra facilmente a diversos frameworks de persistência como JPA, iBATIS, JDBC e proprio Hibernate que iremos demonstrar neste tutorial. Mostrarei
também como desenvolver um DAO generico para o Hibernate que nos da acesso as principais funcões básicas de um CRUD em apenas uma interface, evitando
repetição de código. Modificaremos um pouco o projeto anterior para poder demonstrar todas as funcionalidades dessa integração. Primeiramente precisamos
modificar nosso POM para baixar todas as dependências necessárias:
2 of 7

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema‐instance"


xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven‐v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wordpress.dchohfi</groupId>
<artifactId>ServiceSample</artifactId>
<packaging>war</packaging>
<version>2.0</version>
<developers>
<developer>
<id>dchohfi</id>
<name>Diego Chohfi</name>
<email>diegochohfi@hotmail.com</email>
<url>http://dchohfi.wordpress.com</url>
</developer>
</developers>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven‐compiler‐plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>UTF‐8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven‐jetty‐plugin</artifactId>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
</configuration>
</plugin>
</plugins>

</build>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf‐bundle</artifactId>
<version>2.2.3</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring‐beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring‐context</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring‐core</artifactId>
</exclusion>
<exclusion>
<artifactId>asm</artifactId>
<groupId>asm</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.6.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate‐annotations</artifactId>
<version>3.3.0.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate‐commons‐annotations
</artifactId>
<version>3.3.0.ga</version>
</dependency>
<dependency>
<groupId>commons‐dbcp</groupId>
<artifactId>commons‐dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
</dependency>
<dependency>
<groupId>commons‐collections</groupId>
<artifactId>commons‐collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
3 of 7

Verifique que além das dependências do Spring e do Apache CXF, temos também as dependências do Hibernate. Note que adicionei como dependência o
commons-dbcp da Apache, iremos utiliza-lo para gerenciar nosso pool de conexões ao banco de dados, o Hibernate por default vem com o c3p0 para gerenciar o pool
de conexões, porém eu prefiro o commons-dbcp pois já tive problemas com o c3p0. Portanto, recomendo a vocês utilizarem. O bacana de se utilizar o commons-dbcp
é que podemos ter maior controle sobre como as conexões são abertas e fechadas no Hibernate e também evitar que conexões fiquem abertas sem serem utilizadas.
Vamos ao arquivo de configuração do Spring.
4 of 7

<?xml version="1.0" encoding="UTF‐8"?>


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema‐instance" xmlns:cxf="http://cxf.apache.org/core"
xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring‐beans‐2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring‐context‐2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring‐tx‐2.5.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">

<!‐‐ Carrega as configurações presentes nos jars do Apache CXF ‐‐>


<import resource="classpath:META‐INF/cxf/cxf.xml" />
<import resource="classpath:META‐INF/cxf/cxf‐extension‐soap.xml" />
<import resource="classpath:META‐INF/cxf/cxf‐extension‐jaxrs‐binding.xml" />
<import resource="classpath:META‐INF/cxf/cxf‐servlet.xml" />

<!‐‐ Endpoint WSDL para o Apache CXF ‐‐>


<!‐‐ Dizemos o endereço, o ID do serviço, em qual bean ele depende ‐‐>
<jaxws:endpoint id="service" depends‐on="serviceImpl"
implementor="#serviceImpl" address="/service">
</jaxws:endpoint>

<!‐‐ Mapeamento do REST para o Apache CXF ‐‐>


<jaxrs:server id="myService" address="/rest">
<jaxrs:serviceBeans>
<ref bean="serviceImpl" />
</jaxrs:serviceBeans>
<!‐‐ Aqui declaramos o nosso Mapper para a Exception ‐‐>
<jaxrs:providers>
<ref bean="ClienteExceptionMapper" />
</jaxrs:providers>
</jaxrs:server>

<!‐‐ Referencia ao bean Mapper da nossa Exception ‐‐>


<bean id="ClienteExceptionMapper" class="com.wordpress.dchohfi.exception.ClienteExceptionMapper" />

<!‐‐ Bean que implementa o endpoint do nosso webservice ‐‐>


<bean id="serviceImpl" class="com.wordpress.dchohfi.service.ServiceImpl">
<property name="clienteDAO" ref="clienteHibernateDao" />
</bean>

<!‐‐ Bean abstrato para evitar repetição de código ‐‐>


<bean id="baseSessionFactory" abstract="true">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

<!‐‐ Implementacao da interface ClienteDAO ‐‐>


<bean id="clienteHibernateDao"
class="com.wordpress.dchohfi.model.dao.hibernate.ClienteHibernateDAO"
parent="baseSessionFactory" />

<!‐‐ Carregar arquivos de configuracao ‐‐>


<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:/jdbc.properties</value>
</list>
</property>
</bean>

<!‐‐
&nbsp; &nbsp;&nbsp; &nbsp;Bean com as configuracoes de conexao com o banco, estamos utilizando o
&nbsp; &nbsp;&nbsp; &nbsp;CommonsDBCP da Apache para gerenciar nosso pool de conexão
&nbsp; &nbsp;‐‐>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.pass}" />
<property name="initialSize" value="${database.initConnections}" />
<property name="maxActive" value="${database.maxActive}" />
<property name="maxIdle" value="${database.maxIdle}" />
<property name="removeAbandoned" value="${database.removeAbandoned}" />
</bean>

<!‐‐ Configuracoes de uma fabrica de sessões ‐‐>


<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource" />
</property>
<property name="annotatedClasses">
<list>
<value>com.wordpress.dchohfi.model.entity.Cliente
</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLInnoDBDialect
5 of 7

Leia atentamente os comentários feitos no decorrer do arquivo pois desta vez temos uma configuração mais avançada do Spring, estamos utilizando diversos recursos
disponíveis no framework, um deles é o PropertyPlaceholderConfigurer onde podemos montar um arquivo .properties fora do nosso contexto do Spring e colocar
diversas configurações importantes lá, gosto deste método pois podemos colocar em uma pasta separada, por exemplo, os dados de conexão com o banco, assim
qualquer pessoa pode modificar os dados de configuração se for necessário, sem precisar entender o arquivo de configuração do Spring.

jdbc.properties:
database.driver=com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost:3306/test
database.user=root
database.pass=serviceSample
database.initConnections=1
database.maxActive=10
database.maxIdle=5
database.removeAbandoned=true

A integração do Spring ao Hibernate3 começa quando configuramos nosso sessionFactory, observe que utilizamos a classe AnnotationSessionFactoryBean, aqui
utilizamos um dataSource configurado previamente, dizemos também ao Spring quais são as entidades anotadas com @Entity entre outras diversas configurações
disponíveis. Nós criamos então um Bean abstrato dentro do contexto do Spring para evitar repetição de código, nosso Bean clienteHibernateDao precisa então apenas
herdar nosso bean abstrato para obter a sessionFactory, simples não? No final do arquivo temos também um bean de controle de transações, não pretendo aprofundar
nesse assunto pois criarei outro tutorial abordando apenas controle de transações no Spring pois é um assunto muito bacana. Vamos ao nosso DAO generico integrado
ao Spring.

Precisamos primeiramente de uma interface contendo as operações basicas de um CRUD(criar, ler, atualizar e deletar):

package com.wordpress.dchohfi.model.dao;

public interface GenericDAO<T, ID extends Serializable> {


T findById(ID id);
List<T> listAll();
T save(T entity);
void delete(T entity);
}

Agora vem a "mágica" da integração do Hibernate ao Spring e o DAO generico:


6 of 7

package com.wordpress.dchohfi.model.dao.hibernate;

//Adicionando herança ao HibernateDaoSupport tempos diversas funcionalidades do Spring


//junto ao Hibernate, implementamos também nosso DAO generico para ter mobilidade.
public class HibernateDAOGenerico<T, ID extends Serializable> extends
HibernateDaoSupport implements GenericDAO<T, ID> {

private static Log LOG = LogFactory.getLog(HibernateDAOGenerico.class);

// Nosso construtor vai setar automaticamente via Reflection qual classe


// estamos tratando.
@SuppressWarnings("unchecked")
public HibernateDAOGenerico() {
this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}

// Classe que será persistida.


private Class<T> persistentClass;
public Class<T> getPersistentClass() {
return this.persistentClass;
}

@Override
public void delete(T entity) {
try {
this.getHibernateTemplate().delete(entity);
} catch (final HibernateException ex) {
HibernateDAOGenerico.LOG.error(ex);
throw convertHibernateAccessException(ex);
}
}

@SuppressWarnings("unchecked")
@Override
public T findById(ID id) {
try {
return (T) this.getHibernateTemplate().get(getPersistentClass(), id);
} catch (final HibernateException ex) {
HibernateDAOGenerico.LOG.error(ex);
throw convertHibernateAccessException(ex);
}
}

@Override
public List<T> listAll() {
try {
return this.getHibernateTemplate().loadAll(getPersistentClass());
} catch (final HibernateException ex) {
HibernateDAOGenerico.LOG.error(ex);
throw convertHibernateAccessException(ex);
}
}

@Override
public T save(T entity) {
try {
this.getHibernateTemplate().save(entity);
return entity;
} catch (final HibernateException ex) {
HibernateDAOGenerico.LOG.error(ex);
throw convertHibernateAccessException(ex);
}
}

protected List<T> findByCriteria(Criterion... criterion) {


try {
Criteria crit = this.getHibernateTemplate()
.getSessionFactory()
.getCurrentSession()
.createCriteria(getPersistentClass());
for (Criterion c : criterion) {
crit.add(c);
}
return crit.list();
} catch (final HibernateException ex) {
HibernateDAOGenerico.LOG.error(ex);
throw convertHibernateAccessException(ex);
}
}
}

O nosso DAO generico não precisa saber qual classe ele está relacionando, ele precisa apenas fazer as operações básicas de um CRUD. Porém com o suporte ao
Hibernate temos algo a mais além das operações básicas. Verifique que o método findByCriteria pode receber ou não um Array de Criterion onde podemos fazer
buscas mais específicas no banco de dados.

package com.wordpress.dchohfi.model.dao.hibernate;

public class ClienteHibernateDAO extends HibernateDAOGenerico<Cliente, Long>


implements ClienteDAO {

@Override
public List<Cliente> findClietsWithPhone() {
return findByCriteria(Expression.isNotNull("telefone"), Expression.ne("telefone", ""));
}
}
7 of 7

Nossa implementação de ClienteHibernateDao consegue consultar por exemplo todos os Clientes que possuem telefone, dessa forma você consegue ter um DAO
generico para as operações básicas, mas também tem a opção de fazer buscas mais avançadas via Criteria. Agora você pode ter diversos DAO's utilizando apenas uma
classe, acredite em mim, você da pra economizar muito tempo com isso. O Spring também nos da suporte para tratar as excecões lançadas pelo Hibernate, fica mais
fácil saber o que aconteceu e porque aconteceu e com o controle de transações você não precisa se preocupar em dar rollback caso algum problema aconteça

Veja também que nossa interface de acesso ao serviço não mudou muito:

package com.wordpress.dchohfi.service;

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)


@WebService(endpointInterface = "com.wordpress.dchohfi.service.Service")
public class ServiceImpl implements Service {

private ClienteDAO clienteDao;

@Override
public Cliente getCliente(Long id) throws ClienteException {
Cliente cliente = this.clienteDao.findById(id);
if (cliente == null)
throw new ClienteException("Nenhum usuario com id" + id + " encontrado!");
return cliente;
}

@Override
public Collection<Cliente> getClientes() {
return this.clienteDao.listAll();
}

@Override
public Collection<Cliente> getClientesWithPhone() {
return this.clienteDao.findClietsWithPhone();
}

@Override
public Cliente saveCliente(Cliente cliente) {
return this.clienteDao.save(cliente);
}

public void setClienteDAO(ClienteDAO clienteDao) {


this.clienteDao = clienteDao;
}
}

Note como temos todas as operações de acesso a dados a partir da assunatura da interface, nós não sabemos nem precisamos saber o que acontece. Não se preocupe
com a anotação de @Transactional pois irei explicar em outro post, mas aguarde que o Spring vai se tornar ainda mais interessante.

É importante entender que o nosso projeto ainda está funcionando a partir de interfaces, você, por exemplo, não é obrigado ao utilizar o Hibernate como framework
de acesso a dados, utilizando a interface generica você pode ter acesso via JDBC normal caso você ache necessário, modificando apenas a parte de acesso ao dado.

Acho que isso é tudo, temos agora mais uma demonstração de quanto o Spring Framework é poderoso, integrando ele a outros frameworks podersos temos uma
forma fácil e rápida de implementar aplicações robustas. Utilizei o MySQL para banco de dados e caso você tenha problema com a lib da Sun, você precisa fazer o
download dela diretamente no site para aceitar os termos. Qualquer outra dúvida deixe um comentário ou envie um email.

Obrigado e espero que seja util!

Diego Chohfi Turini


diegochohfi@hotmail.com
http://dchohfi.wordpress.com

Artigos desta série:


WebService WSDL e RESTful com Java e Apache CXF

Leia também:
Acessando Dados com Java: Parte 3 - Hibernate Annotations
Acessando Banco de Dados em Java (PARTE 1)
Acessando Banco de Dados em Java (PARTE 2)
Acessando Banco de Dados em Java (PARTE 3)

comentários: 0

Home Sobre Empregos Blogs Anuncie RSS Notícias


RSS Fórum
O JavaFree.org é uma comunidade java formada pela coolaboração dos desenvolvedores da tecnologia java. A
publicação de artigos além de ajudar a comunidade java, ajuda a dar maior visibilidade para o autor. Contribua conosco.

JavaFree é um site do Grupo DevMedia


www.devmedia.com.br | www.javafree.org | www.mrbool.com |

Você também pode gostar