Как отобразить свойство только для чтения, подкрепленное запросом в Hibernate - PullRequest
0 голосов
/ 25 августа 2010

Мне интересно, как наилучшим образом реализовать свойство (здесь LatestRequest), предназначенное только для чтения, подкрепленное запросом.

Здесь у меня есть экспорт, который может быть запрошенмногократно.Я хотел бы иметь свойство на экспорт, чтобы получить последнюю ExportRequest.В настоящее время у меня есть сопоставление "многие к одному" с формулой, например:

 <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>

Однако, поскольку ExportRequests.Id для LatestRequest выбирается при получении экспорта,этот шаблон доступа возвращает устаревшие данные:

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);

Итак, каков наилучший способ реализации свойства LatestRequest?

Я мог бы изменить геттер для LatestRequest, чтобы он выполнялFind запрос, который должен быть актуальным, но я не уверен, как сделать экспорт осведомленным о сеансе.

1 Ответ

1 голос
/ 25 августа 2010

Есть несколько способов решить эту проблему. Я бы, вероятно, не пытался сделать это «автоматическим» таким образом. Чтобы повысить производительность и простоту, я бы просто сделал это нормальным эталоном и управлял бы им в бизнес-логике или в сущности, например:

class Export
{
  private IList<ExportRequest> requests;

  ExportRequest LatestRequest { get; private set; }

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

Таким образом, вам не нужны ни специальные сопоставления, ни дополнительные запросы для получения последнего запроса. И, что самое важное, сущность согласована в памяти и не зависит от постоянства.

Как бы вы это ни решали, очень важно, чтобы сущность и бизнес-логика управляли данными (в памяти). Это должно быть "невежество упорства". База данных и уровень доступа к данным не несут ответственности за управление отношениями и логикой объектов.

...