NHibernate不会删除孤立的对象

时间:2009-05-14 13:06:12

标签: nhibernate nhibernate-mapping

我有一些看起来像这样的课程

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结构。问题是,虽然我可以向没有实例集(null)的令牌添加新的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: 我错过了现在包含在代码示例中的东西(将原始TokenInstance的令牌引用设置为null)。 另外只是为了澄清这是NHibernate正在生成的SQL;

  1. INSERT INTO TokenInstanceOne(token_id,Id)VALUES(@ p0,@ p1); @ p0 ='4',@ p1 ='32768'
  2. UPDATE令牌SET instance_type = @ p0,instance_id = @ p1 WHERE Id = @ p2; @ p0 ='ClassLibrary1.TokenInstanceOne',@ p1 ='32768',@ p2 ='4'
  3. UPDATE TokenInstanceOne SET token_id = @ p0 WHERE Id = @ p1; @ p0 ='',@ p1 ='1'
  4. 注意最后一次更新是设置token_id ='',我需要的是让NHibernate删除该行。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

抱歉,我误解了你的问题。

你有没有试过在你的任何一端设置inverse =“true”? 或者将级联移动到另一个类的映射。

Read