Quali sono gli errori più comuni e gli anti-schemi dei programmatori utenti NHibernate?


28

Quali sono gli errori più comuni e gli anti-schemi dei programmatori utenti NHibernate? Spiegare perché si tratta di cattive pratiche o fornire collegamenti a risorse per ulteriori letture.

Per esempio:

  • Un anti-pattern comune per i nuovi programmatori NHibernate è l'uso di POID di identità / nativi invece di processi in stile ORM. Leggi di più qui ...

1
Puoi trovare alcuni degli errori più comuni qui: NHProf Alerts

1
Inoltre, ci sono alcuni post preziosi qui sulle insidie ​​di NHibernate

Risposte:


34

I miei problemi personali "spiegati frequentemente":

Anti-pattern

Giocare con oggetti distaccati (SaveOrUpdate o Merge più un po 'di codice disordinato) invece di usare DTO. Più complesse sono le entità, più il codice è disordinato. (Significa anche che funziona abbastanza bene con entità insignificanti.) Ayende lo chiama anche Stripper Pattern e spiega il problema dell'incapsulamento.

Non capire l' ignoranza della persistenza e scrivere applicazioni NH come quando si usa SQL esplicito. Sintomo di ciò: chiamare Update dopo aver modificato un oggetto, chiedendosi perché le modifiche persistano anche se Update non era stato chiamato, chiedendosi come evitare che le modifiche persistessero.

Non capire le transazioni e l' unità del modello di lavoro . Anti-pattern frequenti: transazioni implicite, sessione per operazione e sessione per applicazione. Qualche altra lettura:

Utilizzo degli eventi NH per inserire la logica dell'applicazione (ad es. Rilevamento delle modifiche nei trigger di inserimento e aggiornamento)

Crea una classe per tabella . Alcune persone non capiscono OOD, altre non capiscono il design relazionale.

Errori

uso di uno a uno invece di molti a uno. L'ho provato a spiegare in questa risposta .

Utilizzo di join fetch in combinazione con SetMaxResult. Le mie ultime risposte relative a quell'argomento:

Scrivere entità mutevoli . Quando un'entità non restituisce esattamente il valore impostato da NH, viene considerata sporca e viene aggiornata in ogni sessione. Ad esempio: sostituzione della raccolta persistente NH in un setter proprietà.

  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; }
  }

Potrebbe essere di più sta seguendo.


2
+1: è necessario aggiungere "Non utilizzando il modello Unità di lavoro" e "Una sessione per applicazione" al mio elenco.
Falcon,

@Falcon: sì probabilmente. È un problema generale di "non comprensione delle transazioni". L'unità di lavoro è un po 'coperta dall'ignoranza della persistenza. Sebbene siano concetti completamente diversi, si traducono negli stessi schemi.
Stefan Steinegger,

5

" Seleziona problema N + 1 ".

Qui finisci per eseguire una selezione per ogni entità che vuoi manipolare (N) e una selezione per ottenere l'elenco delle entità (+1), invece di una singola selezione di tutte le entità e dei loro attributi.


1
  • Troppe astrazioni
  • Non usando Automappings con FluentNHibernate

Il primo punto è un po 'vago, ma nel caso in cui vi riferiate a nozioni sciocche come nascondere ISession dietro un "Repository" o "DAO", sono d'accordo.
chris,

1
Il secondo punto è tuttavia senza senso. Ci sono buoni motivi per cui spesso vogliamo avere un controllo granulare sul modello di dati fisici ed essere in grado di disaccoppiarlo dal modello di dominio. Dopo tutto, questo è il punto della "M" in "ORM". L'uso di automappings (sebbene utile in scenari semplici) lo sconfigge. Inoltre, esiste anche il problema degli schemi di database legacy di integrazione, per i quali l'automapping è inutile.
chris,

Uso la mappatura basata sulla convenzione basata sul codice. Gestisce una gran quantità di schifezze che altrimenti avrei dovuto ripetere. Tuttavia, fornisce ancora la libertà di personalizzazione specifica dell'entità che è stratificata sulla mappatura generata dalla convenzione. È super utile.
Sam,

1

Cercando di astrarlo in modo da poter passare a Entity Framework (o qualcos'altro) in un secondo momento.

Questo è molto, molto più difficile della maggior parte delle persone che lo provano. Ci sono numerose differenze tra i due che possono farti inciampare in modi che a volte possono essere abbastanza sottili. È anche molto raro che alla fine sia effettivamente necessario, al punto che puoi provare meticolosamente a implementarlo per anni prima di scoprire che il tuo approccio è tutto sbagliato.

Inoltre, ti impedisce di utilizzare molte delle utili e importanti funzionalità di NHibernate come la memorizzazione nella cache di secondo livello, l'intercettazione, la gestione della concorrenza, il rilevamento delle modifiche, le query di prefetch e così via.

Se fosse davvero necessario passare da NHibernate a Entity Framework, ci sarebbe un progetto attivamente sviluppato per supportare questo su GitHub (forse qualcosa di simile a CommonServiceLocator) con numerosi collaboratori e richieste pull.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.