2010-08-25 3 views
0

Je me demande comment mieux implémenter une propriété (ici, LatestRequest) qui est en lecture seule, soutenue par une requête.Comment mapper une propriété en lecture seule soutenue par une requête dans Hibernate

Ici, j'ai un export, qui peut être demandé plusieurs fois. Je voudrais avoir une propriété sur l'exportation pour obtenir la dernière ExportRequest. En ce moment, j'ai many-to-one mapping avec une formule, comme ceci:

<class name="Export" table="Exports"> 
    <id name="Id"> 
    <generator class="guid" /> 
    </id> 
    <property name="Name" /> 
    <bag name="Requests" cascade="all,delete-orphan" inverse="true" access="field.camelcase" order-by="CreationDate desc"> 
    <key column="ExportId"/> 
    <one-to-many class="ExportRequest"/> 
    </bag> 
    <many-to-one name="LatestRequest" 
       class="ExportRequest" 
       formula="(select top 1 ExportRequests.Id from ExportRequests order by ExportRequests.CreationDate desc)"/> 
</class> 

<class name="ExportRequest" table="ExportRequests"> 
    <id name="Id"> 
    <generator class="native" /> 
    </id> 
    <many-to-one name="Export" 
     class="Export" 
     column="ExportId" 
     not-null="true" /> 
    <property name="CreationDate" /> 
    <property name="Tag" /> 
</class> 

Cependant, depuis le ExportRequests.Id pour LatestRequest est chargé lorsque l'exportation est tiré par les cheveux, ce modèle d'accès renvoie des données périmées :

var export = session.Get<Export>(exportId); 

export.AddRequest(new ExportRequest(DateTime.Now, "Foo")); 

Assert.AreEqual("Foo", export.LatestRequest.Tag); // fails due to stale data 

session.Update(export); 

Alors, quelle est la meilleure façon de mettre en œuvre la propriété LatestRequest?

Je pourrais changer le getter pour LatestRequest afin qu'il exécute une requête Find, qui devrait être à jour, mais je ne suis pas sûr comment faire l'exportation consciente de la session.

Répondre

1

Il existe plusieurs façons de résoudre ce problème. Je n'essaierais probablement pas de le rendre "automatique" de cette façon. Pour améliorer les performances et la simplicité, je voudrais juste faire une référence normale et de le gérer dans la logique métier ou l'entité comme celui-ci:

class Export 
{ 
    private IList<ExportRequest> requests; 

    ExportRequest LatestRequest { get; private set; } 

    public void AddRequest (ExportRequest request) 
    { 
    requests.Add(request); 
    LatestRequest = request; 
    } 
} 

Vous ne avez pas besoin de correspondances spéciales ni des questions supplémentaires pour obtenir le dernière demande Et, plus important encore, l'entité est cohérente dans la mémoire et ne dépend pas de la persistance.

Cependant, vous le résolvez, il est très important que l'entité et la logique métier gère les données (en mémoire). Ce devrait être "la persistance ignorante". La base de données et la couche d'accès aux données ne sont pas responsables de la gestion des relations et de la logique des entités.

Questions connexes