Escolar Documentos
Profissional Documentos
Cultura Documentos
Transao Com o crescimento das aplicaes que vm sendo desenvolvidas um dos maiores problemas na estruturao de um projeto reside no controle de transaes. Quando vrios datasources entram na histria o problema s aumenta. Segue abaixo uma proposta de soluo para o controle de transao utilizando String, com JTA e Maven. As configuraes abaixo necessitam de um container J2EE para funcionarem, o exemplo foi testado no JBoss 4.0.5ga. Com o uso do Spring o controle transacional se torna transparente, sendo ento o problema resolvido. Segue tutorial abaixo: Configuraes do Maven A configurao do Maven para o uso de tais ferramentas simples.
Adicionando dependncias O seguinte trexo deve ser adicionado nas dependncias do projeto no seu arquivo pom.xml.
view plaincopy to clipboardprint? <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>2.5.4</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>2.5.4</version>
</dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>2.5.4</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>2.5.4</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>2.5.4</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>3.3.1.ga</version> </dependency> <dependency> <groupId>javax.persistence</groupId> <artifactId>persistence-api</artifactId> <version>1.0</version> <scope>provided</scope>
</dependency> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.7.0</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate</artifactId> <version>3.2.6.ga</version> <exclusions> <exclusion> <groupId>javax.transaction</groupId> <!-- Exclusion to remove a classloader conflit with jta of JBoss --> <artifactId>jta</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-annotations</artifactId> <version>3.3.1.GA</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-commons-annotations</artifactId> <version>3.3.0.ga</version>
</dependency> Aqui esto listados todos os jars necessrios para o uso das ferramentas mencionadas neste tutorial.
Adicionando repositrio O seguinte trexo deve ser adicionado nos repositrios do projeto para que todas as dependncias sejam satisfeitas.
view plaincopy to clipboardprint? <repository> <id>maven-repository.dev.java.net</id> <name>Java Dev Net Repository</name> <url>http://download.java.net/maven/2/</url> <releases> <enabled>true</enabled> <updatePolicy>never</updatePolicy> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> Utilizao do Spring Com a utilizao do Spring podemos injetar o EntityManager do JPA no Dao, utilizando como provider o Hibernate.
O controle de transao se torna transparente para o desenvolvedor no sendo mais necessrio que o mesmo inicie e finalize cada transao.
Configurao do applicationContext Abaixo segue uma configurao padro para o applicationContext da aplicao
view plaincopy to clipboardprint? <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jboss="http://www.springmodules.org/schema/jboss" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd" default-autowire="byName"> <bean id="dao" scope="prototype" class="br.com.product.project.commons.dao.DaoImpl"> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBea n"> <property name="jpaProperties">
<props> <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATran sactionFactory </prop> <prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transactio n.JBossTransactionManagerLookup </prop> </props> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" > <property name="transactionManagerName" value="java:/TransactionManager" /> <property name="userTransactionName" value="UserTransaction" /> </bean> <tx:annotation-driven transaction-manager="transactionManager" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPost Processor" /> </beans> No xml acima temos vrias configuraes, vamos detalhar uma por uma.
Injeo do Dao na Aplicao No XML acima temos a declarao de um Bean chamado dao. Esse bean implementa o Dao que ser utilizado na nossa aplicao.
Para utiliza-lo devemos fazer com que o Spring injete o mesmo na camada de Aplicao.
Como essa injeo deve ser feita foge o escopo desse tutorial.
Para que o EntityManager seja inicializado no Dao o seguinte fragmento de cdigo deve existir no mesmo:
view plaincopy to clipboardprint? private EntityManager entityManager; @PersistenceContext( type=PersistenceContextType.TRANSACTION, name="name" ) public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } Neste fragmento dizemos ao Spring que a varivel entityManager vai receber uma instncia criada pelo EntityManagerFactory.
Definimos o JpaTransactionManager como o controlador de transaes, e logo abaixo definimos que o mesmo seja feito atravs de annotations.
Logo para definirmos quando um mtodo deve ser executado em uma transao tudo que precisamos fazer adicionar um annotation em cima do mesmo:
view plaincopy to clipboardprint? @Transactional(propagation = Propagation.REQUIRED, readOnly = false) public void someMethod(){ // do some operation in a transaction } O mesmo annotation pode ser adicionado em uma classe ou em uma interface, agindo assim sobre todos os metodos das mesmas.
Programando o DAO Uma vez que possumos o EntityManager injetado no Dao e o controle de transao j est definido a programao do Dao se torna muito simples.
//Consideremos que todas as entidades passadas para esse metodo possuam o metodo getId Object id = t.getId(); if( id != null ){ entityManager.merge( t ); else{ entityManager.persist(t); entityManager.flush(); } catch (Exception e) { throw new DataBaseException( "Erro ao persistir objeto <" + t.getClass().getSimpleName() + ">", e ); } } Mapeamento no Hibernate com Annotations O mapeamento das entidades pode ser feito todo via annotation reduzindo o nmero de XML's para a configurao da aplicao.
O nico XML necessrio o persistence.xml, padro do JPA que explicita as caractersticas na Unidade de Persistencia.
version="1.0"> <persistence-unit name="name" transaction-type="JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:/MySqlAccounter</jta-data-source> <class>br.com.product.project.domain.vo.Home</class> <class>br.com.product.project.domain.vo.Room</class> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" /> <property name="hibernate.cache.use_second_level_cache" value="false" /> <property name="hibernate.cache.use_query_cache" value="false" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.generate_ddl" value="true" /> </properties> </persistence-unit> </persistence> No arquivo configuramos a Unidade de persistencia que ser usada pelo JPA.
Perceba que definimos um nome para a mesma, esse nome o mesmo que deve ser adicionado sobre o entity manager no annotation que o injeta no Dao, mostrado no item Configurao do EntityManager do JPA.
Logo em seguida configurado o endereo do DataSource da base de dados que a Unidade de Persistncia ir utilizar.
Em seguida so listadas todas as classes que queremos mapear para que o JPA possa encontrlas e iniciar o mapeamento das mesmas.
No exemplo o dialeto MySQLDialect usado pois o mesmo se conectar a uma base de dados MySQL, tal varivel deve ser alterada de acordo com o SGBD utilizado, tambm desabilitamos o segundo nvel de cache e a cache de queries.
Annotations de Mapeamento Uma vez que definimos quais classes queremos mapear, agora precisamos inserir metadados nas mesmas para que o mapeamento seja feito corretamente.
view plaincopy to clipboardprint? CREATE TABLE TAB_HOME ( id INT AUTO_INCREMENT PRIMARY KEY, address VARCHAR(50) ); Vejamos um exemplo de mapeamento para a mesma
public void setAddress( String address ){ this.address = address; } } No cdigo usamos o annotation @Entity para mostrarmos que a classe representa uma entidade.
Em seguida usamos o anntation @Table para mostrar qual tabela estamos mapeando.
O annotation @Id mostra que o atributo se referencia a uma chave primria. e o anntation @GeneratedValue que a mesma gerada automaticamente pelo banco de dados.
Em seguida o annotation @Collumn serve para mapear qual a coluna que o atributo se referencia.
Existem vrias anotaes cada uma com seus atributos, veja mais na Documentao Oficial.
Mapeamento de Chaves Estrangeiras Com o JPA podemos mapear as chaves estrangeiras das tabelas para que objetos j sejam inseridos dentro das entidades que as contm. Suponhamos as seguintes tabelas no banco de dados
view plaincopy to clipboardprint? CREATE TABLE TAB_HOME ( id INT AUTO_INCREMENT PRIMARY KEY,
address VARCHAR(50) );
CREATE TABLE TAB_ROOM ( id INT AUTO_INCREMENT PRIMARY KEY, home INT REFERENCES TAB_HOME( id ), size INT, ); Podemos mapear essa chave estrangeira de duas maneiras. Fazendo o Objeto Home ter uma lista de todos os comodos que possui (mapeamento do tipo OneToMany), ou fazendo cada comodo possuir a qual casa ele pertence (Mapeamento do tipo ManyToOne).
Mapeamento OneToMany
Para que possamos ter uma lista em uma entidade pai de todas as entidades filhas que a referenciam utilizamos o mapeamento OneToMany.
Para tanto s precisamos utilizar o annotation @OneToMany ao fazer o mapeamento de um atributo de uma das classes mapeadas.
Vejamos um exemplo:
view plaincopy to clipboardprint? //O atributo mappedby se referencia a uma instancia de Home dentro da classe Room com o nome home @OneToMany( targetEntity=Room.class, mappedby="home" ) private Collection rooms; Com isso ao criar o objeto o mesmo busca uma lista de todos os comodos
Mapeamento ManyToOne
Para que possamos ter uma instncia de um objeto ao qual uma chave estrangeira aponta utilizamos o mapeamento ManyToOne.
Para tanto s precisamos utilizar os annotations @ManyToOne e @JoinColumn ao fazer o mapeamento de um atributo de uma das classes mapeadas.
Vejamos um exemplo:
view plaincopy to clipboardprint? @ManyToOne( targetEntity=Home.class ) @JoinColumn( name="home" ) private Home home; Com isso ao criar o objeto o mesmo busca o objeto ao qual a chave estrangeira se relaciona e o traz de modo lazy.
Mais pode ser encontrado em sites como o de referencia do Spring ou nesse tutorial sobre J2EE.
Por favor, se voc leu esse material deixa sua crtica, comentrio e sujestes de melhoras
[]'s e at a proxima