Pessoal,
Implementei o padrão Open Session in View (http://www.hibernate.org/43.html) em minha aplicacao Web (struts + hibernate) substituindo a loucura que fazia anteriormente: manter uma sessao unica para a aplicacao toda.
A implementacao funcionou legal (ate entao) e corrigiu diversos problemas que eu tinha qdo a sessao "estourava" e excecoes "Flush duranting cascade is dangerous" apareciam no decorrer do dia e o tomcat tinha que ser reiniciado.
No entanto, agora estou com um problemao: a remocao de objetos que possuem relacionamentos um-pra-muitos. Sempre que tento excluir um objeto assim, a excecao java.util.ConcurrentModificationException é lancada e a operacao nao concluir.
O estranho é que a operacao funciona normalmente para objetos que NAO possuem relacionamento com outros. Ex: Funcionario. As demais operacoes, como inclusao, consulta e etc, funcionam tambem normalmente em todo o sistema.
Ao tentar excluir um Cliente por exemplo, que possui uma colecao de Faturas e uma colecao de Servicos, o erro ocorre.
Alguem pode me ajudar?
Abaixo o mapeamento, a implementacao do pattern no Filtro, e os metodos onde ocorrem o problema:
Mapeamento Cliente
<hibernate-mapping>
<class
name="br.com.adok.admin.entidade.Cliente"
>
<id
name="ID"
column="ID"
type="java.lang.Integer"
>
<generator class="increment">
</generator>
</id>
(...)
<set name="servicos" inverse="true" cascade="all-delete-orphan" >
<key column="clienteID"/>
<one-to-many class="br.com.adok.admin.entidade.Servico" />
</set>
<set name="faturas" inverse="true" cascade="all-delete-orphan" >
<key column="clienteID"/>
<one-to-many class="br.com.adok.admin.entidade.Fatura"/>
</set>
(...)
</hibernate-mapping>
Mapeamento de Serviço
<hibernate-mapping>
<class
name="br.com.adok.admin.entidade.Servico"
>
<id name="ID" column="ID" type="java.lang.Integer">
<generator class="increment"/>
</id>
<many-to-one
name="cliente"
class="br.com.adok.admin.entidade.Cliente"
cascade="none"
outer-join="auto"
update="true"
insert="true"
foreign-key="ClienteServicoFK"
column="clienteID"
not-null="true"
/>
(...)
</hibernate-mapping>
Filtro de Sessao implementando Open Session in View
public class FiltroSessao implements Filter {
(...)
public void doFilter(ServletRequest request,ServletResponse response, FilterChain chain) throws ServletException, IOException {
try {
sf.getCurrentSession().beginTransaction();
chain.doFilter(request, response);
sf.getCurrentSession().getTransaction().commit();
} catch (StaleObjectStateException staleEx) {
staleEx.printStackTrace();
throw staleEx;
} catch (Throwable ex) {
trataExcecaoThrowable(ex);
}
}
(...)
}
Action - LancarClienteAction.java
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
(...)
Cliente cliente = (Cliente) Cliente.recuperarPorID(Integer.parseInt(request.getParameter("cod")));
cliente.remover();
}
public void remover() throws HibernateException {
try {
getSession().delete(this);
getSession().flush();
} catch (HibernateException ex) {
throw new RuntimeException(ex);
}
}