Problemas com BMT, Entity and JDBC

Tenho um projeto usando o JBoss 3.0.6 que tem 2 entity beans com uma relacacao CMR many to many. Eu estou tentando usar esses entity beans num Stateful Session Bean, com Bean Managed Transaction. O que estou tentando fazer eh isso:

  1. Pegar e comecar uma UserTransaction
  2. Procurar dois entity
  3. Fazer uma relacao entre ambos
  4. Realizar a chamada JDBC. direta, por um DAO na tabela CMR (many to many)
  5. commitar

Estou usando BMT porque estas operacoes ocorrem entre metodos.

No item 4 acontece o problema. O ResultSet nao tem a, aplicado a base, a relacao criada. A conexao esta na mesma transacao. Eu comecei a investigar o problema, usando um logger sql (p6spy) e descobri que o INSERT eh gerado somente quando vou comitar a transacao.

Fiz uma pesquisa e descobri que se usar um parametro commit-option e usar jdbc diretamente era resultar em um estado de base inconsistente. Coloquei entao em modo C e o problema persistiu. Coloquei tambem uma opcao chamada sync-on-commit-only para false. O INSERT eh gerado somente no commit. I preciso que ele seja gerado antes, para que a chamada JDBC consiga pegar os dados corretos da tabela de relacao.

Alguem tem ideia de como resolver esse problema?

Fala Tanque,

bao amigo, acho BMT meio chato, nao seria mais facil fazer um outro metodo no session bean que fizesse tudo e demarcar a transacao nele?

Outra coisa eh como vc esta fazendo essa relacao cmr? qual eh a navegabilidade? Vc apenas colocou o campo do tipo do remote e fez set?
Como eh n para n, vc pegou a Collection/Set e deu um add??

Como esta o mapeamento atributo cmr X campo tabela.

Outra coisa a verficar eh se o autocommit da sua conexao jdbc esta setado, porque ele nao pode estar!

Abraco,

Obrigado pela atencao, Claudio.
Infelizmente meu problema eh um pouco mais em baixo, vamos la:

Na verdade a minha transacao ela se espalha entre varios requests no servidor web. Assim, poderiamos compara-la a um wizard. Ai minha ideia foi criar um Stateful Session Bean para o cidadao , usando transacao tipo BMT para poder ser a mesma transacao entre metodos de cada um dos requests que o cidadao realizar.
Guardar todas as operacoes para fazer tudo ao final nao eh uma opcao, visto que o wizard eh um pouco complexo, e possui partes que podem ser executada diversas vezes.

A navegabilidade eh bidirecional e eu fiz exatamente como voce descreveu. Eu dei um find nas duas entitadades e usei o add para relacionar uma a outra:

      ALocal a = getALocalHome().findByPrimaryKey(aId);
      BLocal b = getBLocalHome().findByPrimaryKey(bId);
      a.getBs().add(b);

O jboss esta criando uma outra tabela, vista que o relacionamento eh m:n. A principio ela funciona, pois se eu uso transacoes normais, declarativas, funciona.

nao estou mexendo no Connection do JDBC. Alias, ele soh realiza consulta.

Realmente, o problema eh o fato dos dados que vem da conexao do jdbc ainda nao estou com o insert aplicado. O JBoss esta aguardando para dar o insert somente no commit, a fim de poupar o servidor SQL.

Fala Tanque,

bao, se vc quer manter o contexto transacional entre os requests vc vai ter que controla-lo do servidor web o que te traz problemas gravissmos:

  1. Lock dos Entity beans
  2. Timeout da Transacao
  3. Armazenamento do Contexto Transacional

se quer trabalhar no modelo de wizard por exemplo, por que vc nao mantem apenas um vo na session web ou dentro de um statefull e vai populando ele aos poucos e cria a trancao apenas no ultimo passo do wizard?

Isso resolveria o problema da transacao e da incosistencia dos dados, vc apenas faria uma comparacao entre os dados que vc pegaria em um dado instante com os dados que estao no vo.

Abraco,

Tenho ciencia de todos esses problemas, claudio. Irei aborda-los, com certeza, mas de outras formas. O lock de entity beans nao seria um problema, na verdade, poderia chama-lo de feature, inclusive. Os Timeouts sao facilmente resolvido com timers e o Armazenamento do contexto transacional eh muito facilitado pelo Statefull Session Bean. Basta guarda-lo na sessao do usuario, ou num mapa estatico no servlet, e ao fim do wizard destruir esse statefull session bean.

Como falei no meu post anterior, usar um VO ou algo semelhante para guardar todos os meus passos eh algo nao aceitavel. Eu realmente preferiria reflexos na base de dados. Isso porque realmente , um select seria uma mao na roda para mim. Vou explicar um pouco mais o que desejo fazer.

No meu wizard eu estou pegando entidades A e associando/desassociando com entitidades B. Esse processo pode ser repetido indefinidamente no meu wizard, ate que o usuario nao queira mais. Alem disso , as entitidades A podem ser filtradas por uma serie de criterios (selects diretos em JDBC).

Caso eu “imaginasse” em guardar as associacoes / desassociacoes “na mao”, em um VO, isso equivaleria a dizer que logo apos a consulta sql, eu deveria percorrer a lista dos elementos ja associados e desassociados na transacao para “ajustar” a resposta do select. Essas associacoes tb podem ocorrer nao somente de um elemento, mas tambem em um criterio, tipo, associe todas as entidades A que sigam essa caracteristica com B.

Logo, logo teria que ter todos os registros da entidade A e B na memoria, e passar praticamente a usar dois vetores e migrar os elementos de um vetor para o outro. Isso seria aceitavel em um universo, de digamos, 100 registros, no maximo 200. Mas em um conjunto de 50000, 100000 registros, nao tem condicao.

Nao preciso nem dizer , que isso gerara muito mais problemas que aqueles 3 itens anteriores, pois ai sim terei dados inconsistentes, pois eles estao na memoria, pouca concorrencia caso eu faca o lock da tabela toda , alem de ser um desperdicio de memoria. Isso sem contar que caso eu tenha que associar objetos A em B seguindo um criterio, o procedimento sera visitar todas as entidades A e verificar , via IF, se devo associa-lo ou nao. Usar um select seria muito melhor, com certeza.

Agradeco mesmo assim a ajuda, amigo Claudio.

Excelente tutorial de JDBC…

http://developer.java.sun.com/developer/onlineTraining/Programming/JDCBook/jdbc.html

Bom estudo…