Quais são os erros e antipadrões mais comuns cometidos pelos programadores do NHibernate?

28

Quais são os erros e antipadrões mais comuns cometidos pelos programadores do NHibernate? Por favor, explique por que essas são práticas inadequadas ou dê um link para o recurso para leitura adicional.

Por exemplo:

  • Um antipadrão comum para os novos programadores do NHibernate é usar identidades / POIDs nativos em vez de estilo ORM. Leia mais aqui ...
Darius Kucinskas
fonte
1
Você pode encontrar alguns dos erros mais comuns aqui: Alertas NHProf
1
Além disso, existem algumas mensagens valiosas aqui sobre NHibernate Armadilhas

Respostas:

34

Meus problemas pessoais "frequentemente explicados":

Anti-Padrões

Brincando com objetos desanexados (SaveOrUpdate ou Merge mais algum código confuso) em vez de usar DTOs. Quanto mais complexas as entidades, mais confuso é o código. (Isso também significa que funciona muito bem com entidades triviais.) Ayende também o chama de Stripper Pattern e explica a questão do encapsulamento.

Não entendendo a ignorância da persistência e escrevendo aplicativos NH como ao usar SQL explícito. Sintoma disso: chamar o Update após alterar um objeto, perguntando-se por que as alterações persistem, mesmo que o Update não tenha sido chamado, perguntando-se como evitar que as alterações sejam persistidas.

Não compreendendo transações e o padrão de unidade de trabalho . Antipadrões frequentes: transações implícitas, sessão por operação e sessão por aplicativo. Um pouco mais de leitura:

Usando eventos NH para inserir a lógica do aplicativo (por exemplo, rastreamento de alterações nos gatilhos de inserção e atualização)

Crie uma classe por tabela . Algumas pessoas não entendem OOD, outras não entendem o design relacional.

Erros

uso de um para um em vez de muitos para um. Eu tentei explicar nesta resposta .

Usando junção buscar em combinação com SetMaxResult. Minhas respostas mais recentes relacionadas a esse tópico:

Escrevendo entidades que mudam automaticamente . Quando uma entidade não retorna exatamente o valor que foi definido pelo NH, ela é considerada suja e atualizada em todas as sessões. Por exemplo: substituindo a coleção persistente NH em um configurador de propriedades.

  IList<Address> Addresses
  {
    get { return addresses; }
    // will cause the addresses collection to be built up from scratch
    // in the database in every session, even when just reading the entity.
    set { addresses = new List<Address>(value); }
  }

  int Whatever
  {
    // will make the entity dirty after reading negative values from the db.
    // this causes unexpected updates after just reading the entity.
    get { if (whatever < 0) return 0; }
    set { whatever = value; }
  }

Pode ser mais está seguindo.

Stefan Steinegger
fonte
2
+1: você deve adicionar "Não usar padrão de unidade de trabalho" e "Uma sessão por aplicativo" à sua lista.
Falcon
@ Falcon: sim, provavelmente. É um problema geral de "não entender transações". A unidade de trabalho é um pouco coberta pela persistência da ignorância. Embora sejam conceitos completamente diferentes, eles resultam nos mesmos padrões.
Stefan Steinegger
5

O " Selecione o problema N + 1 ".

É aí que você acaba executando uma seleção para cada entidade que deseja manipular (N) e uma seleção para obter a lista de entidades (+1), em vez de uma única seleção de todas as entidades e seus atributos.

Sean McMillan
fonte
1
  • Abstrações demais
  • Não usar Automappings com FluentNHibernate
Sly
fonte
O primeiro ponto é um pouco vago, mas no caso de você estar se referindo a noções tolas, como esconder ISession por trás de um "Repositório" ou "DAO", eu concordo.
21414 chris
1
O segundo ponto, no entanto, é um absurdo. Há boas razões pelas quais geralmente queremos ter um controle refinado sobre o modelo de dados físicos e poder dissociá-lo do modelo de domínio. Afinal, esse é o ponto do "M" em "ORM". O uso de automappings (embora útil em cenários simples) anula isso. Além disso, há também a questão dos esquemas de banco de dados herdados de integração, para os quais o mapeamento automático é inútil.
chris
Eu uso o embutido por mapeamento baseado em convenção de código. Ele lida com uma grande quantidade de porcaria que eu teria que repetir. No entanto, ele ainda oferece a liberdade, mas a customização específica da entidade que é colocada sobre o mapeamento gerado pela convenção. É super útil.
Sam
1

Tentando abstraí-lo para que você possa alternar para o Entity Framework (ou qualquer outra coisa) em uma data posterior.

Isso é muito, muito mais difícil do que a maioria das pessoas que tentam perceber. Existem inúmeras diferenças entre os dois que podem te enganar de maneiras que podem ser bastante sutis às vezes. Também é muito incomum que seja realmente necessário no final - tanto que você pode tentar meticulosamente implementá-lo por anos antes de descobrir que sua abordagem está errada.

Além disso, impede você de usar muitos recursos úteis e importantes do NHibernate, como cache de segundo nível, interceptação, gerenciamento de simultaneidade, rastreamento de alterações, consultas de pré-busca e assim por diante.

Se realmente houvesse uma necessidade válida de alternar entre o NHibernate e o Entity Framework, haveria um projeto desenvolvido ativamente para dar suporte a isso no GitHub (talvez algo semelhante ao CommonServiceLocator) com vários contribuidores e solicitações pull.

jammycakes
fonte