8
votes

Forcer l'entité paresseuse à charger une instance réelle

J'ai un proxy pour une entité paresseuse qui a été créée dans la session en chargement d'une entité infantile. Une récupération ultérieure sur l'entité mère ne renvoie que le proxy NH. J'ai besoin de l'instance réelle pour vérifier le type (l'entité a rejoint les sous-classes). Je dois manquer quelque chose, mais je ne peux pas trouver un moyen de faire cela. Session.Refresh (proxy) ne semble pas aider, ni aucune saveur de HQL que j'ai essayée.

Quelqu'un peut-il aider?


2 commentaires

Pourriez-vous montrer comment vos objets de domaine apparent et les requêtes HQL que vous avez essayées jusqu'à présent?


Je ne suis pas sûr de pouvoir présenter cette quantité d'informations dans ce format. Impensez-vous qu'il devrait être possible d'écrire une requête HQL qui ignore les proxies correspondant au cache?


4 Réponses :


-2
votes

Étant donné que le proxy est dérivé de la classe d'entité, vous pouvez probablement simplement vérifier l'entité.getType (). BaseType pour obtenir votre type défini.


2 commentaires

Non, il ne peut pas. "L'entité a rejoint les sous-classes". Cela signifie que le proxy sera toujours dérivé de la classe de base de cette hiérarchie et non de la classe concrete (à l'époque, Nhibernate crée le proxy, il ne sait pas ce que le type d'entité est!). Sam veut vérifier lequel des sous-types est.


Cela a du sens ... raté ça.



12
votes

Pour forcer un proxy à extraire de la base de données, vous pouvez utiliser la méthode NhibernateUtil.initialiser (proxy) code> ou accéder à une méthode / propriété du proxy.

session.Evict(myEntity);


3 commentaires

Non, cela ne fonctionne pas - on dirait que cette méthode est destinée à remplir un proxy existant avec des données et ne chargez pas une nouvelle instance du type correct. Je suppose que je suis après un mécanisme pour effacer un objet proxy spécifique du cache (sans effacer toute la session) afin que lorsque je reçoive, il renvoie le type correct.


OK, j'ai mis à jour la réponse avec des informations sur la manière de supprimer un objet du cache de session.


Cela a fait le truc Erik, merci - je ne suis pas sûr de savoir comment j'ai manqué celui-là.



21
votes

À mon avis, résolvez plutôt ce problème, vous devriez plutôt repenser votre conception. Êtes-vous absolument sûr que vous ne pouvez pas utiliser de polymorphisme dans cette situation - soit directement responsable de l'opération que vous essayez d'effectuer ou d'utiliser un motif de visiteur. Je suis tombé sur cette question peu de fois et j'ai toujours décidé de changer de conception - il a entraîné un code plus clair. Je vous suggère de faire la même chose, sauf si vous êtes absolument sûr que vous comptez sur le type est la meilleure solution.

Le problème H2>

Afin d'avoir un exemple avec au moins une certaine ressemblance au monde réel, Supposons que vous ayez des entités suivantes: p>

Operation[] operations = { transfer, withdrawal, proxy };
foreach (var operation in operations)
{
    operation.Accept(visitor);
}


3 commentaires

Fondamentalement, j'essaie d'afficher un formulaire différent (Windows) pour chaque sous-classe, lorsqu'une ligne est double-cliquée dans une liste. Je suis ouvert aux suggestions pour un meilleur design (qui n'implique pas de code de présentation dans le modèle de domaine).


Puis-je vous amener à élaborer sur la solution polymorphe? Mon problème principal est que le proxy est dérivé du type de base, et non de la sous-classe, donc je ne précise pas comment cela va accomplir la mise en œuvre de la sous-classe correcte de l'opération.


Merci pour l'explication. Personnellement, je ne vois pas d'avantages sociaux de maintenance de cette solution sur «Si OBJ est sous-type» avec un chèque de proxy explicite - c'est un compromis entre la laideur perçue et le plus de code. Notez que mes sous-classes dans cette situation sont très centrées sur les données - je peux avoir une opinion différente dans un scénario différent.



3
votes

Désactiver le chargement paresseux obligera l'instance réelle à être renvoyée à la place du proxy NHibernate.

par exemple ..

mappage.not.lazyload ();

ou < / p> xxx


0 commentaires