Pergunta

Estamos usando o padrão DTO para mobilizar nossos objetos de domínio da camada de serviço em nosso repositório, em seguida, para baixo para o banco de dados via NHibernate.

eu correr em um problema no qual eu puxo um DTO para fora do repositório (por exemplo CustomerDTO) e depois convertê-lo em objeto de domínio (Customer) na minha camada de serviço. Eu, então, tentar salvar um novo objeto de volta (por exemplo SalesOrder) que contém o mesmo objeto Cliente. Esta por sua vez é convertido para um SalesOrderDTO (e CustomerDTO) para empurrar para o repositório.

NHibernate não gosta this- ele reclama que o CustomerDTO é um registro duplicado. Estou assumindo que isso é porque ele tirou o primeiro CustomerDTO na mesma sessão e porque o retorno foi de volta convertido e para trás não pode reconhecer este como o mesmo objeto.

Am I preso aqui ou se existe uma maneira de contornar isso?

Graças

James

Foi útil?

Solução

Você pode re-anexar um objeto para uma sessão no NHibernate usando Lock -. Por exemplo

_session.Lock(myDetachedObject, NHibernate.LockMode.None);

que pode ou não pode ajudar, dependendo exatamente o que está acontecendo aqui. Em uma nota lateral, usando DTO com NHibernate não é a prática mais comum, o fato de que NHibernate (principalmente) suportes de persistência meios ignorância desse tipicamente DTO não são tão amplamente utilizado como com alguns outros frameworks ORM.

Outras dicas

É realmente sobre como sessão NHibernate funciona. Então, se você dentro de um puxão sessão de uma instância de sua CustomerDTO e, em seguida, depois de um tempo você deve obter o mesmo CustomerDTO (dizem por chave primária.) - você realmente vai ter referência ao mesmo objeto como você fez na sua primeira recuperação

Então, o que você faz é que você quer mesclar os objetos chamando Session.merge ou você perguntar a sua sessão para o objeto chamando session.get (primaryKey) fazer suas atualizações e lave a sessão.

No entanto, como sugerido por Steve - este não é geralmente o que você faz - você realmente deseja receber o seu objeto de domínio do armazenamento de dados e uso de DTOs (se neede) para transferir os dados para UI, webservice o que quer ...

Como outros já mencionado, Equals execução e GetHashCode é um passo na direção certa. Também olhar para o apoio do NHibernate para o "anexar" OR / M idioma.

Você também tem a opção nosetter.camelcase à sua disposição: http://davybrion.com/blog/2009/03/entities-required-properties-and-properties-that-shouldnt-be-modified/

Além disso, eu gostaria de encorajá-lo para não ser dissuadido pela falta de informação lá fora online. Isso não significa que você é louco, ou fazendo coisas erradas. Significa apenas que você está trabalhando em um caso extremo. Infelizmente os maiores consumidores de bibliotecas como NHibernate são pequenos em casa e / ou aplicações web, onde não existe a liberdade para se apoiar todas as suas necessidades de persistência contra um único banco de dados. Na realidade, existem muitas excepções a esta regra.

Por exemplo, eu estou trabalhando atualmente em um aplicativo de desktop comercial, onde um dos meus objetos de domínio tem a sua propagação de dados entre um banco de dados arquivos de imagem e SQL CE no disco. Infelizmente NHibernate só pode me ajudar com a persistência SQL CE. Eu sou forçado a usar uma espécie de "Double Mapping" (ver "Padrões de do Martin Fowler Enterprise Application Architecture ") mapear o meu modelo de domínio através de uma camada de repositório que sabe quais dados vai para NHibernate e que para o disco.

Acontece. É uma necessidade real. Às vezes, uma aparente falta de uma ferramenta indica que você está tomando uma abordagem ruim. Mas às vezes a verdade é que você só realmente estão em um caso extremo, e necessidade de construir alguns desses padrões para si mesmo para fazê-lo.

Eu estou supondo que isto é porque tirou o primeiro CustomerDTO em a mesma sessão e porque o retornando foi convertido para trás e diante ele não pode reconhecer este como o mesmo objeto.

Você tem razão. Hibernate não pode. Considere Equals e Hashcode de execução para corrigir isso. Eu acho que um re-anexar só pode funcionar se você não tiver carregado o objeto dentro desta sessão.

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