(Hibernate) - Illegal attempt to associate a collection with two open sessions

Pessoal, estou passando pelo seguinte problema: Tenho uma entidade chamada pedido que possui um relacionamento OneToMany com a entidade estoque, quando tento salvar a entidade pedido no banco de dados utilizando o Hibernate a seguinte exception é lançada.

Illegal attempt to associate a collection with two open sessions

Já procurei e vi vários tópicos falando sobre o assunto, porém nenhum me ajudou a resolver o problema, pois minha sessão com o HIbernate é criada em uma classe que herda de Filter pois tenho entidades com lazy loading.

Abaixo segue os códigos do Filtro e do HibernateUtil


public class HibernateUtil {

    private static HibernateUtil hibernateUtil;
    private SessionFactory sessionFactory;    
    
    private HibernateUtil() {
        try {
            //sessionFactory = new Configuration().configure("com/i9/webpedidos/entity/hibernate.cfg.xml").buildSessionFactory();            
            sessionFactory = new AnnotationConfiguration().setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect").
                    setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver").
                    setProperty("hibernate.connection.url", "").
                    setProperty("hibernate.connection.username", "").
                    setProperty("hibernate.connection.password", "").
                    setProperty("hibernate.show_sql", "true").
                    setProperty("hibernate.format_sql", "true")                   
                    .addAnnotatedClass(Cidade.class)
                    .addAnnotatedClass(Condpgto.class)
                    .addAnnotatedClass(Cor.class)
                    .addAnnotatedClass(Duplicata.class)
                    .addAnnotatedClass(Empresa.class)
                    .addAnnotatedClass(Estoque.class)
                    .addAnnotatedClass(Formapgto.class)
                    .addAnnotatedClass(Linkcondpgtopessoa.class)
                    .addAnnotatedClass(Linkvc.class)
                    .addAnnotatedClass(Pedido.class)
                    .addAnnotatedClass(Pessoa.class)
                    .addAnnotatedClass(Produto.class)
                    .addAnnotatedClass(Produtocor.class)
                    .addAnnotatedClass(Produtoest.class)
                    .addAnnotatedClass(Produtofml.class)
                    .addAnnotatedClass(Produtolnh.class)
                    .addAnnotatedClass(Tabpreco.class)
                    .addAnnotatedClass(Tabprecoitem.class)
                    .addAnnotatedClass(Desconto.class)
                    .addAnnotatedClass(Linkdescontopessoa.class)
                    .buildSessionFactory();

        } catch (HibernateException ex) {
            System.err.print("ERRO HIBERNATE ----------------------------------------" + ex.getMessage());
            ex.printStackTrace();
        }//end catch
    }//end method

    public static HibernateUtil getInstance() {
        if (hibernateUtil == null) {
            hibernateUtil = new HibernateUtil();
        }//end if
        return hibernateUtil;
    }//end getInstance

    public  SessionFactory getSessionFactory(){        
        return sessionFactory;
    }
    
    public Session getSession() {
        try {
            return sessionFactory.openSession();
        } catch (HibernateException e) {
            System.err.println(e.getMessage() + "CUSTOM MESSAGE");
            return null;
        }//end catch
    }//end method        
}//end class

@WebFilter(filterName = "HibernateSessionRequestFilter", urlPatterns = {"/*"})
public class HibernateSessionRequestFilter implements Filter {
        
 
    public static final String HIBERNATE_SESSION_KEY = "hbmSession";
    private SessionFactory sf;
 
    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain)
            throws IOException, ServletException { 
 
        Session curSession = null;
        
        HttpSession httpSession =
                ((HttpServletRequest) request).getSession();
        
        Session disconnectedSession =
                (Session) httpSession.getAttribute(HIBERNATE_SESSION_KEY);
        
        try {
        
            if(disconnectedSession == null){ 
                
                if(!disconnectedSession.isOpen()){
                
                    curSession = sf.openSession();
                
                }
                curSession.setFlushMode(FlushMode.NEVER);
                
            }else{
                
                curSession = (org.hibernate.classic.Session) disconnectedSession;                
                
            }
            
            ManagedSessionContext.bind(curSession);
                                    
            curSession.beginTransaction();
             
            chain.doFilter(request, response);
 
            curSession = ManagedSessionContext.unbind(sf);
                        
            sf.getCurrentSession().getTransaction().commit();
                  
            curSession.flush();
            
            curSession.getTransaction().commit();
            
            curSession.close();
            
            httpSession.setAttribute(HIBERNATE_SESSION_KEY, null);
            
        } catch (StaleObjectStateException staleEx) {
                        
            throw staleEx;
        } catch (Throwable ex) {

            ex.printStackTrace();
            try {
                if (sf.getCurrentSession().getTransaction().isActive()) {
                    
                    sf.getCurrentSession().getTransaction().rollback();
                }
            } catch (Throwable rbEx) {
                
            }    
            throw new ServletException(ex);
        }
        
    }
 
    public void init(FilterConfig filterConfig) throws ServletException {        
        sf = HibernateUtil.getInstance().getSessionFactory();
    }
 
    public void destroy() {}
 
}

Resolvi o problema alterando o meu Filtro adicionando a seguinte linha:

httpSession.setAttribute(HIBERNATE_SESSION_KEY, curSession);

Estou colocando minha sessão do hibernate em uma httpsession e recupero ela no meu método AbstractDao sempre que preciso. Ao invés de criar uma nova sessão o meu DAO vai pegar a sessão já existente…

@WebFilter(filterName = "HibernateSessionRequestFilter", urlPatterns = {"/*"})
public class HibernateSessionRequestFilter implements Filter {
        
 
    public static final String HIBERNATE_SESSION_KEY = "hbmSession";
    private SessionFactory sf;
 
    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain)
            throws IOException, ServletException { 
// chain.doFilter(request, response);
 
        Session curSession = null;
        
        HttpSession httpSession =
                ((HttpServletRequest) request).getSession();
        
        Session disconnectedSession =
                (Session) httpSession.getAttribute(HIBERNATE_SESSION_KEY);
        
        try {
        
            if(disconnectedSession == null){ 

                
                    curSession = sf.openSession();
                    
                    httpSession.setAttribute(HIBERNATE_SESSION_KEY, curSession);

                curSession.setFlushMode(FlushMode.NEVER);
                
            }else{
                
                curSession = (org.hibernate.classic.Session) disconnectedSession;                
                
            }
            
            ManagedSessionContext.bind(curSession);
                                    
            curSession.beginTransaction();
 
            // Call the next filter (continue request processing)
            chain.doFilter(request, response);
 
            //curSession = ManagedSessionContext.unbind(sf);
            // Commit and cleanup
            
            //sf.getCurrentSession().getTransaction().commit();
        
            
            //curSession.flush();
            
            //curSession.getTransaction().commit();
            
            //curSession.close();
            
            //httpSession.setAttribute(HIBERNATE_SESSION_KEY, null);
            
        } catch (StaleObjectStateException staleEx) {
            
            
            // 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()) {
                    
                    sf.getCurrentSession().getTransaction().rollback();
                }
            } catch (Throwable rbEx) {
                
            }
 
            // Let others handle it... maybe another interceptor for exceptions?
            throw new ServletException(ex);
        }
        
    }
 
    public void init(FilterConfig filterConfig) throws ServletException {        
        sf = HibernateUtil.getInstance().getSessionFactory();
    }
 
    public void destroy() {}
 
}


public class AbstractDao {
    
    public static final String HIBERNATE_SESSION_KEY = "hbmSession";
    
    protected Session session;
    
    protected Session getSession(){  
        //FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(HIBERNATE_SESSION_KEY, HibernateUtil.getInstance().getSession());
        //return HibernateUtil.getInstance().getSession();        
        return (Session) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(HIBERNATE_SESSION_KEY);
    }//end method

...

}