NHibernate.MappingException: NHibernate.PropertyNotFoundException: не удалось найти получатель для свойства в классе - PullRequest
1 голос
/ 27 июня 2019

Возникли проблемы с отображением моего перечисления в базу данных с помощью nHibernate.

Попытался посмотреть на сопоставление, но не вижу в этом ничего плохого, на данный момент я подозреваю, что оно может иметь какое-то отношение к перечислению?

Вот Fortron.Crm.Domain.Policy:

namespace Fortron.Crm.Domain
{
   [Serializable]
   public class Policy
   {
      private PolicyStatus _policyStatus;

      public PolicyStatus PolicyStatus
      {
          get { return _policyStatus; }
          set { _policyStatus = value; }
      }
   }

Вот отображение классов

  <class name="Fortron.Crm.Domain.Policy, Fortron.Crm.Domain" table="Policy" lazy="false">
    <id name="Id" access="nosetter.camelcase-underscore" column="PolicyId" unsaved-value="-1">
      <generator class="identity" />
    </id>
    <set name="Claims" access="field.camelcase-underscore" inverse="true" lazy="false" cascade="save-update">
      <key column="PolicyId" />
      <one-to-many class="Fortron.Crm.Domain.Claim, Fortron.Crm.Domain" />
    </set>
    <many-to-one name="Product" column="ProductId" access="nosetter.camelcase-underscore" />
    <property name="PolicyNumber" />
    <property name="VehicleRegistrationNumber" />
    <property name="ContractNumber" />
    <property name="ContractPaymentAuthorised" />
    <property name="ContractPaymentAuthorisedAt" />
    <component name="Contact" access="nosetter.camelcase-underscore">
      <property name="Title" />
      <property name="GivenNames" />
      <property name="Surname" />
      <property name="BusinessName" />
      <property name="DateOfBirth" />
      <property name="Gender" column="GenderId" />
      <property name="TelephoneNumber" />
      <property name="MobileTelephoneNumber" />
      <property name="WorkTelephoneNumber" />
      <component name="Address" access="nosetter.camelcase-underscore">
        <property name="StreetLine1" column="StreetLine1" />
        <property name="StreetLine2" column="StreetLine2" />
        <property name="CityTown" column="CityTown" />
        <property name="Postcode" column="Postcode" />
        <many-to-one name="StateTerritory" column="StateTerritoryId" />
      </component>
    </component>
    <property name="CustomerNumber" column="CustomerNumber" not-null="false" />
    <property name="Vin" column="Vin" not-null="false"  />
    <property name="PolicyStatus" column="PolicyStatusId" />
  </class>

Наконец, вот трассировка стека:

Service cannot be started. System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> NHibernate.MappingException: Could not compile the mapping document: Fortron.Crm.Domain.Policy.hbm.xml ---> NHibernate.MappingException: Problem trying to set property type by reflection ---> NHibernate.MappingException: class Fortron.Crm.Domain.Policy, Fortron.Crm.Domain, Version=2.0.0.1, Culture=neutral, PublicKeyToken=6f168f2566a816b4 not found while looking for property: PolicyStatus ---> NHibernate.PropertyNotFoundException: Could not find a getter for property 'PolicyStatus' in class 'Fortron.Crm.Domain.Policy'
   at NHibernate.Properties.BasicPropertyAccessor.GetGetter(Type type, String propertyName)
   at NHibernate.Util.ReflectHelper.ReflectedPropertyClass(String className, String name, String accessorName)
   --- End of inner exception stack trace ---
   at NHibernate.Util.ReflectHelper.ReflectedPropertyClass(String className, String name, String accessorName)
   at NHibernate.Mapping....

Есть идеи?

1 Ответ

0 голосов
/ 28 июня 2019

Измените свою подпись члена, чтобы сделать это virtual:

public virtual PolicyStatus PolicyStatus

NHibernate ожидает, что все члены вашей организации будут virtual для привязки. Это необходимо, потому что NHibernate создает прокси (для реализации отложенной загрузки) в некоторых случаях. Без пометки как virtual это не будет возможно для NHibernate.

Вы можете сослаться на эту (или архив ) статью:

Быстрый ответ на этот вопрос: потому что нам нужно, чтобы участники были виртуальными, чтобы выполнять нашу ленивую загрузочную магию / вуду.

Чем длиннее ответ, тем интереснее. Важной особенностью, которую должен иметь любой настоящий ORM, является прозрачная Lazy Loading. Если вы извлекаете объект через ORM, вы не хотите, чтобы он автоматически вытягивал весь граф объектов (в любом случае, по умолчанию), но вы не хотите засорять свой код проверками, чтобы увидеть, были ли загружены определенные ассоциации еще, а затем загружать их при необходимости. Это ответственность ОРМ. В идеале вы хотите иметь возможность доступа к свойствам, и ORM загружает необходимые данные при первом доступе к этим свойствам, если данные еще не получены.

NHibernate обладает этой способностью, но не требует, чтобы вы наследовали от какого-то базового класса NHibernate или реализовывали какие-либо интерфейсы или что-то в этом роде. Итак, как это работает? Ну, NHibernate использует прокси ваших классов во время выполнения всякий раз, когда требуется отложенная загрузка. Хорошо, так что же такое прокси? В этом случае прокси-сервер NHibernate - это тип, который генерируется динамически, когда NHibernate инициализируется для вашего приложения (это происходит только один раз при запуске приложения). Тип прокси будет сгенерирован для каждой вашей сущности, которая не была явно отображена, чтобы избежать отложенной загрузки (подробнее об этом позже). Тип прокси для одной из ваших сущностей будет наследоваться от вашей сущности, а затем перехватывать все возможные вызовы, которые вы можете выполнить для этого типа.

...