NHibernate не удалит осиротевший объект - PullRequest
0 голосов
/ 14 мая 2009

У меня есть несколько классов, которые выглядят так

public class Token
{
    public int Id
    {
        get;
        set;
    }

    public ITokenInstance Instance
    {
        get;
        set;
    }
}

public interface ITokenInstance
{
    int Id
    {
        get;
        set;
    }

    Token Token
    {
        get;
        set;
    }
}

и файлы сопоставления


<class name="Token" >
   <id name="Id" >
      <generator class="hilo" />
   </id>

   <any name="Instance" meta-type="class" id-type="Int32" cascade="all-delete-orphan">
      <column  name="instance_type" />        
      <column name="instance_id" />
   </any>
</class>

<class name="TokenInstanceOne" >
   <id name="Id" >
      <generator class="hilo" />
   </id>

   <many-to-one name="Token" class="Token" column="token_id"/>
</class>

У меня есть различные реализации интерфейса ITokenInstance, все они смотрят в разные таблицы, но все используют ту же структуру baisc, как показано в отображении. Проблема в том, что, хотя я могу добавить новый ITokenInstance в токен, у которого нет установленного экземпляра (ноль), и он будет обновляться правильно, я НЕ могу добавить новый экземпляр в токен, который уже получил экземпляр, а затем обновить его, NHibernate добавьте новый экземпляр, который я предоставляю, но не удаляйте теперь не назначенный экземпляр. Например

Token token = Session.Get<Token>(4);
var instance = Session.Get<TokenInstanceOne>(1);
Assert.AreSame(token.Instance, instance);

var newInstance = new TokenInstanceOne();
token.Instance = newInstance;
newInstance.Token = token;
instance.Token = null;
Session.Flush();

Это запускает SQL для вставки нового TokenInstance и обновляет таблицу токенов, чтобы указывать на него, НЕ удаляет экземпляр, для которого изначально был установлен токен. Кто-нибудь знает, как я могу поручить NHibernate удалить оригинальный TokenInstance из базы данных

Eidt: Я пропустил что-то, что теперь включено в пример кода (установив исходную ссылку Token TokenInstance на null). Также просто чтобы уточнить, что это SQL NHibernate производит;

  1. INSERT INTO TokenInstanceOne (token_id, Id) VALUES (@ p0, @ p1); @ p0 = '4', @ p1 = '32768'
  2. ОБНОВЛЕНИЕ токена SET instance_type = @ p0, instance_id = @ p1 WHERE Id = @ p2; @ p0 = 'ClassLibrary1.TokenInstanceOne', @ p1 = '32768', @ p2 = '4'
  3. ОБНОВЛЕНИЕ TokenInstanceOne SET token_id = @ p0 WHERE Id = @ p1; @ p0 = '', @ p1 = '1'

Обратите внимание, что последнее обновление устанавливает token_id = '', мне нужно, чтобы NHibernate удалил строку.

Ответы [ 2 ]

2 голосов
/ 14 мая 2009

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

Это ваш код:

var token = Session.Get<Token>(4);
Assert.IsNotNull(token.Instance);

// remove the old token
Session.Delete(token.Instance);

// assign the new token
var newInstance = new TokenInstance();
token.Instance = newInstance;
newInstance.Token = token;

// don't need to call update, the token is in the session.
// (except you turned off session flush)
// Session.Update(token);
0 голосов
/ 14 мая 2009

Извините, я неправильно понял ваш вопрос.

Вы пытались установить inverse = "true" на любом конце? Или переместите каскад в отображение другого класса.

Читать

...