Pour résumer, il existe deux manières de récupérer des entités depuis une session nhibernate:

  • le "get" sur l'identité de l'entité
  • les requêtes (que ce soit par sql, hql, ou criteria)

Dans le cadre ou nous voulons récupérer une seule entité, normalement le get est la solution la plus performante, d'autant plus qu'il est capable de chercher dans le cache de premier niveau pour voire si nous n'avons pas déjà une référence (ce qui arrive bien plus souvent qu'on pense). La requête pour aller chercher une résultat unique n'est pas capable de chercher dans le cache, et va en plus émettre un flush pour être sûr d'être consistante.

Pourquoi est-ce que je vous dis tout ça? Et bien parce qu'une veille croyance de l'informatique à laquelle je m'accrochais moi-même consistait à dire que toute entité à un identifiant interne gérée par la base (le bon vieux int auto-increment), et que tout ce qui est idendité "fonctionnelle", comme par exemple un numéro de sécurité sociale, une plaque d'immatriculation, un numéro de compte etc etc etc, n'est pas considérée comme clef primaire par besoin de "simplification".

Le problème de cette approche, vous l'avez peut être deviné, est que nous allons la grande majorité du temps aller chercher nos entités via ces identifiants fonctionnelles plutôt que par l'identifiant auto générée. Nous passons ainsi à côté de toute la puissance du "get" standard de nhibernate, et passons notre temps à faire des auto-flush plus ou moins coûteux pour aller chercher des entités que nous avons en plus déjà en cache de premier niveau là plupart du temps. Le cache de second niveau dans notre cas nous a permis de résoudre en partie ce problème, mais ce n'est qu'une astuce qui camoufle un problème de fond.

Donc, ma conclusion serait de ne pas hésiter à déclarer comme identifiant des notions plus fonctionnelles. Si elles nous garantissent l'unicité et l'identité d'une entité, pourquoi utiliser autre chose qui plus est complètement dépourvu de sens?