Concernant la première question. Si vous allez juste lire l'entité, vous n'avez rien à faire. Même si vous l'attribuez en tant que champ à une entité différente, vous ne devrez pas verrouiller l'enregistrement. La seule raison pour laquelle vous devez appeler ISession.Lock
est lorsque vous voulez muter, puis enregistrer l'entité.
Il existe une exception, à savoir le chargement paresseux. Si l'entité a des enregistrements enfant étrangers qui n'ont pas été chargés alors que la première session était active, une exception sera levée lorsque vous tenterez d'y accéder plus tard. La façon la plus simple de se déplacer est de toucher les collections d'enfants en première session.
Si l'entité vous pose toujours des problèmes dans ces circonstances, vous pouvez ajouter un Load
à votre référentiel. Vous pouvez câbler ceci à ISession.Load
. Qu'est-ce que Load
est de créer un proxy vide pour l'entité sans frapper la base de données. Cette entité fait partie de la session dans laquelle l'entité est chargée et peut être utilisée pour affecter des propriétés à d'autres entités. L'avantage de cette approche est qu'elle est beaucoup plus propre et qu'il est facile de se moquer des tests unitaires.
Concernant la deuxième question. Oui, vous avez raison, ça sent l'intégration de ISession.Lock
dans un dépôt. Encore une fois, lorsque vous n'avez pas à muter l'entité, vous n'avez pas à vous en préoccuper. Mais, quand vous êtes, eh bien, vous devriez vraiment penser à simplement recharger l'entité à partir du dépôt et travailler sur celui-ci. Je sais que ce n'est pas aussi optimal que possible, mais cela vous permet d'économiser beaucoup de code très étrange, particulièrement dans vos tests unitaires.
Une dernière chose. Je comprends que vous parlez d'une entité qui va vivre longtemps (peut-être l'exécution complète de l'application). Vous avez à peu près trois catégories de vie: 1. pour toujours, 2. long et 3. court. La raison pour laquelle je mentionne cela est que plus d'une fois, les problèmes avec des entités qui ont une «longue» durée de vie pourraient vraiment rester connectés à une session qui a la même durée de vie. Ce n'est pas un problème d'avoir une session en vie par exemple, 5 ou 10 minutes (le temps que l'utilisateur entre des données dans un formulaire). Cela seul permettra d'économiser beaucoup de gens beaucoup d'ennuis.
Encore une note: jetez un oeil à NHibernateUtil
et NHibernateProxyHelper
. Ces classes peuvent vous aider à forcer le chargement des entités et des collections enfants.
Pourquoi conservez-vous des entités en mémoire après la fermeture de la session? Je n'ai jamais eu besoin de faire ça. – Paco
@Paco: Je crée beaucoup de nouvelles entités qui référencent des entités existantes, déjà persistées. – Groo
Je veux dire pourquoi les gardez-vous en mémoire au lieu de les récupérer dans la base de données? Cela ne causera-t-il pas une base de données corrompue quand une transaction échoue? – Paco