Bonjour à tous,

Voila mon problème, j'ai une application web basée sur Struts 1 et Hibernate ... J'utilise le mecanisme de gestion d'exception de Struts pour capter les exceptions qui provient des actions ou de la partie metier (afin de logger l'exception en error et pour envoyer un message d'erreur ds attribut de la request). Pour la gestion des transactions hibernate j'utilise le pattern "open session in view" d'hibernate qui consiste simplement a filtrer toute les requetes en ouvrant une transaction avant l'execution de l'action et a faire le commit juste apres que l'action soit executé ou un roolback si un exception est capté.

Le problème est que vu que je capte l'exception au niveau de l'exceptionHandler, le filtre hibernate ne recoit jamais l'exception et commit systématiquement la transaction (mm en cas d'erreur). Malheureusement il n'est pas possible de relancer l'exception ds l'exceptionHandler ...

Alors comment faire pour afficher un message d'erreur ds la vue courrante en utilisant ExceptionHandler et le filtre hibernate en mm temps ?

Voici le filtre :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
 
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
 
package be.vincentcolet.util.db;
 
import java.io.IOException;
 
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;
import org.hibernate.StaleObjectStateException;
 
/**
 *
 * @author xxx
 */
public class HibernateSessionRequestFilter implements Filter {
 
 
    private static final Logger log = Logger.getLogger(HibernateSessionRequestFilter.class);
 
    private SessionFactory sf;
 
 
    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain)
            throws IOException, ServletException {
 
        try {
            log.debug("Starting a database transaction");
            sf.getCurrentSession().beginTransaction();
 
            // Call the next filter (continue request processing)
            chain.doFilter(request, response);
 
            // Commit and cleanup
            log.debug("Committing the database transaction");
            sf.getCurrentSession().getTransaction().commit();
 
        } catch (StaleObjectStateException staleEx) {
            log.error("This interceptor does not implement optimistic concurrency control!");
            log.error("Your application will not work until you add compensation actions!");
            // Rollback, close everything, possibly compensate for any permanent changes
            // during the conversation, and finally restart business conversation. Maybe
            // give the user of the application a chance to merge some of his work with
            // fresh data... what you do here depends on your applications design.
            throw staleEx;
        } catch (Throwable ex) {
            // Rollback only
            ex.printStackTrace();
            try {
                if (sf.getCurrentSession().getTransaction().isActive()) {
                    log.debug("Trying to rollback database transaction after exception");
                    sf.getCurrentSession().getTransaction().rollback();
                }
            } catch (Throwable rbEx) {
                log.error("Could not rollback transaction after exception!", rbEx);
            }
 
            // Let others handle it... maybe another interceptor for exceptions?
            throw new ServletException(ex);
        }
    }
 
    public void init(FilterConfig filterConfig) throws ServletException {
        log.debug("Initializing filter...");
        log.debug("Obtaining SessionFactory from static HibernateUtil singleton");
        sf = HibernateUtil.getSessionFactory();
    }
 
    public void destroy() {}
 
}
et mon exception handler :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package be.vincentcolet.controller;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.apache.struts.Globals;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ExceptionHandler;
import org.apache.struts.config.ExceptionConfig;
 
/**
 *
 * @author xxx
 */
public class ExceptionLoggingHandler extends ExceptionHandler {
 
    private final static String ERROR = "error";
    private final static Logger LOG = Logger.getLogger(ExceptionLoggingHandler.class);
 
    @Override
    public ActionForward execute(Exception e, ExceptionConfig p2, ActionMapping mapping, ActionForm p4, HttpServletRequest request, HttpServletResponse p6) {
 
        LOG.error("Exception:", e);
        request.setAttribute(Globals.EXCEPTION_KEY, e);
 
        return mapping.findForward(ERROR);
    }
}