Struts 2 + AJAX + JPA + Spring – Parte VI
Integrando JPA ao Spring
Agora vamos configurar para que o spring instancie nosso EntityManagerFactory para que possamos acessar o banco de dados, tendo nossos daos configurados como spring beans.
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
Criamos um bean chamado transactionManager, estamos aqui utilizando nomes comuns podem usar qualquer nome para o atributo id que serve para o spring identificá-los e você poder instanciá-los em outros objetos.
No atributo class informamos o nome da classe e pacote que ela pertence, temos agora a tag <property/> que como parametro possue name que é o nome da propriedade, ou seja nome do atributo da classe, ref é que se esta atribuindo uma referencia ao objeto entityManagerFactory que é um bean no Spring.
Temos também a propriedade chamada dataSource que recebe uma referencia do bean dataSource, abaixo temos a tag <tx:annotation-driven/> que possui o parâmetro transaction-manager que passamos o bean transactionManager.
Mas, nos não criamos isso? Para que declaramos esses beans e esse annotation-driven?
Isso é utilizado pelo Spring para podermos instanciar nosso EntityManagerFactory configurando todos seus parâmetros e ainda dar suporte as annotations da especificação EJB 3.0, ou seja, estamos preparando o spring para se integrar a JPA.
Agora vamos criar o bean dataSource.
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/javamagazine"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
Neste bean iremos configurar nosso dataSource, vocês podem ver que estaremos delegando ao spring todas as funções de instanciação de nossas actions e daos, como também nossas classes de serviço. A utilização de spring pode ser útil ate na utilização de webservices, mas acredito que isso seja assunto para um outro artigo.
Temos as propriedades driverClassName onde informamos o nome do driver, url onde configuramos nossa url de conexão, e as propriedades username e password são como o próprio nome diz, usuário e senha do banco de dados.
Com nosso dataSource pronto só nos resta agora criamos nosso bean entityManagerFactory para que possamos instanciar nossos daos.
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="testeStruts"></property>
<property name="dataSource" ref="dataSource"></property>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"></bean>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL"></property>
<property name="showSql" value="true"></property>
<property name="generateDdl" value="true"></property>
</bean>
</property>
</bean>
A primeira propriedade é persistenceUnitName que é atribuído o valor testeStruts que esta configurado no arquivo persistence.xml, que seria o lugar onde normalmente iríamos configurar nossa url de conexão, usuário, senha, etc., aqui criamos sim o arquivo persistence.xml e configuramos uma unidade de persistência, mas apenas configuramos o nome para testeStruts nada mais, como podem ver na listagem 17.
Configuramos a propriedade dataSource do nosso bean entityManagerFactory com uma referencia ao bean dataSource que criamos.
Temos a propriedade jpaDialect que tem que ser criada apontando para a classe org.springframework.orm.jpa.vendor.HibernateJpaDialect que possui as propriedades que nos permite configurarmos a implementação do hibernate da JPA.
Agora na propriedade jpaVendorAdapter criamos um bean para a classe org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter que possui as algumas propriedades que nos iremos configurar neste artigo para podermos criar nosso EntityManagerFactor, são a propriedade dataBase onde informaremos MYSQL que é o banco que estaremos utilizando, a propriedade showSql com o valor true, para que seja exibido a sql gerada pelo hibernate.
E por fim a propriedade generateDdl com o valor configurado para true para que ele crie nossas tabelas caso essas não existam, se existirem não serão recriadas, semelhante a atribuir o valor update na propriedade hibernate.hbm2ddl.auto que é a que também estamos usando aqui, só não estamos vendo diretamente.
Pronto agora o spring já esta configurado para nos fornecer um EntityManagerFactory que possamos utilizar para acessar o banco de dados.
Mas, ate agora deu um trabalho para configurar o spring com jpa, o que temos que fazer para instanciar nossos daos?
<bean id="loginDao" class="br.jm.persistencia.LoginDAO">
<constructor-arg ref="entityManagerFactory"></constructor-arg>
</bean>
<bean id="contatoDao" class="br.jm.persistencia.ContatoDAO">
<constructor-arg ref="entityManagerFactory"></constructor-arg>
</bean>
Criamos um bean loginDao que é a classe LoginDAO e recebe no construtor a referencia para o bean entityManagerFactory e o bean contatoDao também recebe no construtor uma referencia ao bean entityManagerFactory.
Pronto nossos dois daos, já tiveram suas dependências configuradas e sempre que precisarmos teremos nossos daos prontos para o uso.
Vamos ver nossos serviços que irão prover o acesso ao banco de dados para nossas actions.
<bean id="servicoContato" class="br.jm.servico.ContatoImpl" scope="singleton">
<property name="contatoDAO" ref="contatoDao"></property>
</bean>
<bean id="servicoLogin" class="br.jm.servico.LoginImpl" scope="singleton">
<property name="loginDAO" ref="loginDao"></property>
</bean>
Aqui está sendo utilizado a Setter Injection, pois ate agora estávamos utilizando a Constructor Injection a propriedade do bean servicoContato contatoDAO será usado o seu método set para injetar o bean contadoDao.
Assim também foi configurado o servicoLogin, só que já estamos utilizando outro atributo chamado scope que configuramos como singleton que para criar somente uma instancia desse objeto, vamos ver a outra opção vendo nossas actions.