fiz um interceptor para controlar minhas transações com o banco de dados e analisando as atividades dela percebi que ela abre várias transações para executar um comando salvar
lista de ações
interception
interception
inicia a transacao
comita transação
interception
interception
inicia a transacao
comita transação
interception
interception
inicia a transacao
Hibernate:
insert
into
Estado
(nome, uf)
values
(?, ?)
comita transação
interception
interception
inicia a transacao
comita transação
Sempre que você tiver uma dúvida sobre vraptor, poste sempre no subfórum específico: Índice dos Fóruns » Frameworks e Bibliotecas brasileiros. Além disso lembre-se de sempre dizer a versão que você usa. Só notei que você está usando vraptor por causa dos pacotes br.com.caelum.vraptor.
Conforme já conversamos em outro tópico com o vraptor você não precisa trabalhar com transações manualmente. Creio pelo seu relato de abrir várias transações é por que você abre transação manual e o vraptor também abre outra transação. Isso só dá para saber vendo como você configurou no web.xml. Se por acaso você configurou o componente para controle do Hibernate do vraptor e tenta usar esse manual certamente vai dar um comportamento estranho.
Eu gosto das coisas mais automatizadas, então já que o vraptor possui (via Spring) um controle automatico não apenas de transação mas de controle da hibernate session porque vocẽ não a usa? A grande vantagem é poder trabalhar de forma transparente. Isso é bom por que você deixa tudo a cargo do vraptor, não precisando dar manutenção em mais uma classe em seu sistema. Além do mais as classes do vraptor são exaustivamente testadas, garantindo o bom funcionamento.
Mas se você quer fazer o controle manual, o que nada lhe impede, desabilite os componentes de controle de session-factory que estão no seu web.xml e use apenas o seu componente.
Além do mais, olhando seu componente, o método accepts está retornando true quando você não tiver a anotação HibernateTransaction. Isso significa que sempre que você não tiver a anotação no método ele executa a transação. Não seria o contrário?
Outra coisa… finnaly SEMPRE é executado, ou seja, você faz commit e depois um rollback logo abaixo?
package smcv.dao;
import java.util.List;
import org.hibernate.Session;
import br.com.caelum.vraptor.ioc.Component;
import smcv.infra.HibernateTransaction;
import smcv.modelo.area.Estado;
@Component
public class DAO<T> {
private Session session;
public DAO(Session session) {
this.session = session;
}
@HibernateTransaction
public void adiciona(T reg) {
this.session.save(reg);
}
public void remove(T reg) {
this.remove(reg);
}
}
e no meu xml não tem nada configurado
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>Sistema de Mapeamento e Controle de Vetores</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- configura o controlador do VRaptor -->
<filter>
<filter-name>vraptor</filter-name>
<filter-class>br.com.caelum.vraptor.VRaptor</filter-class>
</filter>
<filter-mapping>
<filter-name>vraptor</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<jsp-config>
<jsp-property-group>
<description>Mapeamento</description>
<display-name>Mapeamento de Vetores</display-name>
<url-pattern>*.jsp</url-pattern>
<include-prelude>/header.jspf</include-prelude>
<include-coda>/footer.jspf</include-coda>
</jsp-property-group>
</jsp-config>
</web-app>
como eu posso fazer isso no meu projeto conforme as classes que eu te passei?
Eu estou completamente confuso, o que eu quero é fazer com que meu sistema execute ações no banco sem ter que ficar abrindo transações manuais e que de alguma forma eu possa gravar logs no banco para fazer auditoria, estou lendo bastante artigos e vários tópicos nos forum e to ficando cada vez mais confuso.
Primeira coisa a fazer é remover as suas classes que cuidam de transação, creio que sejam elas: TransactionInterceptor, HibernateTransaction, HibernateHelper e CriadorDeSessoes. Ou seja, remova tudo que você tem de classes que fazem a tarefa de cuidar do Hibernate manualmente.
Agora apenas adicione as tags no seu web.xml. Isso vai dizer para o vraptor cuidar das transações e também de iniciar o hibernate.
Feito isso você só precisa colocar a sua Session no construtor das classes que você quer trabalhar com o Hibernate. Assim toda vez que a classe for chamada o Vraptor verá que tem um objeto session lá e irá não apenas inicializar a sessão como fará o devido controle transacional. Muito simples e prático.
Aproveitando o DAO que você postou aqui, ela ficaria conforme abaixo. Note que você apenas declara sua session na classe e no construtor. Assim toda vez que você chamar essa classe o Vraptor vai injetar a session aí para você e fará o controle de transação com os devidos commits e rollbacks. Lembrando que o padrão é sempre commit, porém caso alguma filha de RuntimeException for lançada será feito um rollback, seguindo o padrão J2EE.
[code]@Component
public class DAO {
private Session session;
public DAO(Session session) {
this.session = session;
}
public void adiciona(T reg) {
session.save(reg);
}
public void remove(T reg) {
session.remove(reg);
}
}[/code]
Vocẽ quer fazer um interceptor para auditar as alterações no banco de dados (insert, update e delete) ou você quer apenas gravar a URL de acesso?
Hmm, adora notei que você usa generics em dua DAO. Não sei como o Vraptor trabalha com isso, mas o Lucas ou o Paulo Silveira podem te ajudar melhor quanto a isso. Se você procurar no subfórum de frameworks brasileiros há uma extensa thread sobre isso.
Mas creio que para você usar em seu controller basta fazer algo assim:
[code]@Resource
public class UserController {
private DAO userDAO;
public UserController(DAO<User> userDAO) {
this.userDAO = userDAO;
}
Sobre a dúvida das transações, você conseguiu fazer funcionar direitinho? Me reporte tuas dúvidas e/ou problemas que você possa ter tido. Além do mais se você não entendeu alguma coisa avise-me.
Sobre auditoria, aconselho você a usar o Envers, que faz essa auditoria detalhada. Há um artigo muito bom na Javamagazine de uns 2 meses atrás se não me engano. Ele faz a aditoria completa e transparente de tudo que mudou no projeto, bastando você anotar as classes com @Audit (se não me engano).
Na verdão 3.5 do Hibernate o envers vem já no core. Nas versões anteriores você precisa baixar separado. Tenho usado em um projeto grande que tenho e tem me atendido muito bem. Uma pequena que só funcione com Hibernate, e não com qualquer implementação de JPA.
garcia, muito obrigado pelas ajudas, agora ta funcionando certinho como você me disse só falta a parte de auditoria, vc sabe mais algum lugar inde posso achar um tutoria legal sobre Envers além da revista javamagazzine?