Question

J'ai un problème étrange dans mon projet actuel. Le chargement différé pour les requêtes ne fonctionne pas. Lorsque j'interroge une liste, nhibernate extrait toutes les associations séparément.

J'en ai extrait de petites parties et les ai mises dans une solution séparée. Fondamentalement, ce que j'ai maintenant, est une table de compte et une table AccountSync. Les deux ont un identifiant et une URL, tandis que l'identifiant n'est qu'un db-guid.

Mes cours sont les suivants:

public class HippoAccount
{
    public virtual Guid Id { get; set; }
    public virtual string Url { get; set; }
    public virtual HippoAccountSync Sync { get; set; }
}

public class HippoAccountSync
{
    public virtual Guid Id { get; set; }

    public virtual string Url { get; set; }
    public virtual HippoAccount Account { get; set; }
}

Quand je charge maintenant un objet via son guide:

var account = session.Load<HippoAccount>(accountId);
Console.WriteLine(NHibernateUtil.IsPropertyInitialized(account, "Sync"))

... il renvoie false et le compte lui-même est un proxy.

Mais lors du chargement d'une liste via l'API de critères:

var account = (HippoAccount)session
    .CreateCriteria(typeof (HippoAccount))
    .Add(Restrictions.Eq("Id", accountId))
    .List()[0];

... la propriété Sync est initialisée (en déclenchant une seconde requête de sélection) et l'objet renvoyé n'est pas un proxy.

Ce comportement par défaut? Qu'est-ce que je me trompe?

Le mappage est:

<class name="HippoAccount" table="AllAccounts">
  <id name="Id" type="guid">
    <generator class="guid"/>
  </id>
  <property name="Url" />

  <many-to-one 
           class="HippoAccountSync"
           name="Sync"
           not-found="ignore"
           property-ref="Url">
    <column name="url" />
  </many-to-one>
</class>

<class name="HippoAccountSync"
       mutable="false"
       table="Accounts">

  <id name="Id" type="guid">
    <generator class="guid"/>
  </id>

  <property name="Url">
    <column name="serviceUri" />
  </property>

  <many-to-one class="HippoAccount"
               name="Account"
               property-ref="Url"
               not-found="ignore">

    <column name="serviceUri" />
  </many-to-one>

</class>
Était-ce utile?

La solution

Après quelques recherches supplémentaires, j'ai trouvé les réponses. Réponses, car de nombreux facteurs peuvent empêcher le chargement paresseux dans NHibernate.

  1. Requête ou session.Load: Lors de la récupération d'un élément via session.Load () , vous obtenez un proxy. Mais dès que vous accédez à une propriété , disons le URL , l'objet est récupéré, y compris toutes les associations qui ne prennent pas en charge le chargement différé.

  2. référence de propriété: le chargement différé ne fonctionne que sur un identifiant d'objet. Lorsqu'une association de propriétés est résolue via une colonne différente dans l'entité cible, NH le recherche avec impatience. Cela ne serait pas possible, ce n'est tout simplement pas implémenté: Bug

  3. not-found = "ignorer" autorise les clés invalides , c'est-à-dire que si l'entité référencée n'est pas trouvée, NH initiera la propriété avec nul. NH n'intercepte pas l'accès de propriété pour un chargement différé, mais assigne à la place un proxy d'objet. Avec not-found = "ignore" , il ne peut pas décider si la propriété doit avoir la valeur null ou un proxy pour la clé étrangère donnée, éventuellement non valide. Cela pourrait éventuellement être résolu en interceptant l'accès à la propriété.

  4. Lors de la désactivation de not-found = "ignorer" et de property-ref , l'exportation de schéma générerait des contraintes qui imposent une référence circulaire. Pas bon! Le mappage correct serait alors une relation un à un contrainte, où la clé pour HippoAccountSync doit avoir un générateur foreign .

Ressources

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top