Pergunta

Editar 5/11/2011:

Eu acho que é um pouco pior do que o que está abaixo; no meu exemplo QA implantado, se eu apenas atualizar o principal painel de um número de vezes, eventualmente, o meu usuário é muitos-para-muitos associações de grupo são eliminadas. Neste ponto, há apenas declarações select sendo chamado no lado do servidor; espero que eu estou ficando é estreitada para baixo com estes últimos testes.

Original:

Oi tudo. Estou tendo um problema com um objeto bastante complexo; problema é o seguinte: quando eu enviar o objeto do cliente para o servidor para ser salvo, é aparentemente limpando aleatoriamente muitos-para-muitos relacionamentos em objetos associados. Pior ainda, eu não sou capaz de reproduzir o problema sozinho, depois de cerca de dois meses de estar ciente do problema. Eu tenho o aplicativo para teste com um grupo de controle de qualidade; eles estão usando o programa diário, double inserindo nos novos e legados aplicações. O problema surge tanto quanto três vezes por dia.

Vou fazer o meu melhor para fornecer o máximo de detalhes que puder, e muito aprecio qualquer um tomar um olhar!

O quadro aplicativo é GWT 2.1 + Gilead + Hibernate 3 + MySQL InnoDB. Eu estou deixando Hibernate lidar com qualquer cascata etc, de modo nenhum está definido na DB, embora todas as chaves estrangeiras são definidos no DB.

Eis alguns trechos dos mapeamentos:

<hibernate-mapping>
 <class name="com.example.domain.Close" table="CLOSE">

 <many-to-one name="updateUser"
class="com.example.domain.User"
column="LAST_UPDATE_USER"/>
 </class>
</hibernate-mapping>

<hibernate-mapping>
  <class name="com.example.domain.User" table="USER" batch-size="25">
    <set name="groups" table="USER_GROUP" lazy="true" batch-size="25">
      <key column="USER_ID"/>
      <many-to-many column="GROUP_ID" class="com.example.domain.Group"/>
    </set>
  </class>
</hibernate-mapping>

<hibernate-mapping>
  <class name="com.example.domain.Group" 
    table="GROUP" batch-size="25">
    <set name="users" table="USER_GROUP" lazy="true" inverse="true">
      <key column="GROUP_ID"/>
      <many-to-many column="USER_ID" class="com.example.domain.User"/>
    </set>
    <set name="permissions" table="PERMISSION_GROUP" lazy="true" inverse="true">
    <key column="GROUP_ID"/>
    <many-to-many column="PERMISSION_ID" 
      class="com.example.domain.Permission"/>
    </set>

<hibernate-mapping>
  <class name="com.example.domain.Permission" 
      table="PERMISSION">
    <set name="groups" table="PERMISSION_GROUP" lazy="true">
      <key column="PERMISSION_ID"/>
      <many-to-many column="GROUP_ID" 
        class="com.example.domain.Group"/>
    </set>
  </class>
</hibernate-mapping>

Como salvar o objeto é chamar um simples saveOrUpdate ():

Session session = gileadHibernateUtil.getSessionFactory()
  .getCurrentSession();
session.beginTransaction();
try {
  session.saveOrUpdate(close);
} catch (Exception e) {
  e.printStackTrace();
  session.getTransaction.rollback();
}
session.getTransaction.commit();

return close;

O Close 'updateUser' é um objeto carregado quando o usuário fizer login. Ele é carregado com os grupos e permissões associadas para que o sistema pode conceder / negar acesso aos módulos de aplicativos. Eu faço

close.setUpdateUser(exampleApp.getUser()); 

antes de enviar o objeto de volta para o servidor.

Há uma abundância de outros lugares do aplicativo onde este tipo de operação acontece, mas não causa os efeitos colaterais indesejados. Ele provavelmente se resume à complexidade do código do lado do cliente associado ao próximo objeto, ou melhor, minha implementação do mesmo.

Eu passei tanto tempo derramando sobre os documentos oficiais do Hibernate, à procura de problemas possivelmente relacionados, etc, eu pensei que talvez fosse um bom momento para pedir ajuda. Eu tenho que o homem e mantê-la, mas talvez apenas pedindo vai me ajudar a descobrir isso.

Eu não tenho certeza o que mais para fornecer agora que é relevante. Esperemos que o que está aqui até agora tem relevância!

Obrigado por escutar!

Editar

May  5 12:18:38 localhost jsvc.exec[10117]: Hibernate: insert into example_dev.RECENT_ITEM (OBJECT_TYPE, OBJECT_ID, DATE, USER_ID) values (?, ?, ?, ?)
May  5 12:18:38 localhost jsvc.exec[10117]: Hibernate: delete from example_dev.PERMISSION_GROUP where PERMISSION_ID=?
May  5 12:18:38 localhost last message repeated 19 times
May  5 12:18:38 localhost jsvc.exec[10117]: Hibernate: delete from example_dev.USER_GROUP where USER_ID=?
May  5 12:18:38 localhost jsvc.exec[10117]: Hibernate: delete from example_dev.USER_DESIGNATION where USER_ID=?

Parece que exclusões estão acontecendo logo após esta inserção .. operações anteriores são todos seleciona. Mas nada no usuário deve ser em cascata a partir RecentItem.

Foi útil?

Solução

Depois de muita pesquisa, cheguei a algumas conclusões e foi capaz de tomar medidas. Primeiro, eu aprendi depois de um pouco de pesquisar no fórum Gilead, que já não está sendo mantido ativamente . Deve ter notado que, mais cedo. Enquanto isso, eu tinha começado a ler sobre RequestFactory, e depois de alguns dias de pesquisa, decidi que eu deveria tentar migrar para isso.

Este é um projeto bastante grande, cerca de 50 objetos de domínio, alguns com muitas associações de objeto. Ele me levou cerca de 40-50 horas para reescrever tudo, desde usando Gilead + GWT RPC para usar RequestFactory exclusivamente. Estou muito feliz com as mudanças resultantes no código e estrutura. Eu não estou muito preocupado, até agora, por ter que criar objetos proxy DTO, e eu aproveitei a oportunidade para mudar para o Hibernate Annotations, livrar-se dos arquivos de mapeamento.

Foi complicado às vezes para refatorar o código para utilizar o fetch / editar / salvar ciclos que RequestFactory requer. Ele me deu a oportunidade de melhorar a parte do código.

A boa notícia é, o problema foi resolvido. Não há mais muitos-para-muitos associações sendo misteriosamente apagados. Meu melhor palpite é que eu estava acertando um bug no Gilead, ou o meu uso dele estava errada, ou é possível que eu resolvido um problema ao migrar para anotações.

deparei com alguns grandes recursos ao mesmo tempo aprender RequestFactory + Hibernate, muitos através de StackOverflow (obrigado novamente!):

Usando GWT RequestFactory com Objectify - foi ótimo ter uma idéia de como RequestFactory interagiu com o back-end, e alguns métodos e clichê para reduzir código

.

Mais links abaixo espero .. Eu ainda sou um noob assim que eu estou limitado em # de hiperlinks eu posso postar:)

Eu aprendi muito, e estou recebendo fluente em RequestFactory. Vou fazer o meu melhor para manter um olho para fora e ajudar aqui onde eu acho que posso.

Graças StackOverflow!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top