为什么NHibernate删除然后在select上插入复合元素?

时间:2009-07-21 11:01:07

标签: nhibernate

有人可以向我解释NHibernate如何处理复合元素的这个小谜。

我的课程看起来像这样;

public class Blog
{
    public virtual int Id
    {
        get;
        private set;
    }

    public virtual ISet<Comment> Comments
    {
        get;
        set;
    }
}

public class Comment
{
    public virtual string CommentText
    {
        get;
        set;
    }

    public virtual DateTime Date
    {
        get;
        set;
    }
}

和这样的映射;

<class name="Blog" table="blog">
    <id name="Id" column="id" unsaved-value="0">
      <generator class="hilo"/>
    </id>

    <set name="Comments" table="blog_comments">
      <key column="blog_id" />
      <composite-element class="Comment">
        <property name="CommentText" column="comment" not-null="true" />
        <property name="Date" column="date" not-null="true" />
      </composite-element>
    </set>

  </class>

然而,当我执行这样的选择时;


using (ITransaction transaction = session.BeginTransaction())
{
    Blog blog = session.CreateCriteria(typeof(Blog))
                  .SetFetchMode("Comments", FetchMode.Eager)
                  .Add(Expression.IdEq(2345))            
                  .UniqueResult();

    transaction.Commit();
}

NHibernate发布带有连接的select以获取带有帖子的博客但是删除所有注释然后插入注释!它为什么这样做?如果我不使用事务,那么它将只执行select而不是我期望的DELETE和INSERT。我错过了什么?我正在使用NHibernate 2.0

2 个答案:

答案 0 :(得分:6)

我认为你需要在Comment上覆盖Equals()和GetHashCode()。 NHibernate没有用于实体相等的ID,因此您必须定义使注释实体等于另一个注释的内容。

可能是错的:)


修改

来自:http://www.nhforge.org/doc/nh/en/index.html#components-incollections(7.2)

  

注意:如果定义复合元素的ISet,则正确实现Equals()和GetHashCode()非常重要。

实现Equals / GetHashCode

的示例

http://www.nhforge.org/doc/nh/en/index.html#persistent-classes-equalshashcode(4.3)

答案 1 :(得分:-1)

如果您只需要选择,我的问题就是您提交的原因?我相信它删除所有注释的原因是,当您在事务上调用commit时,博客对象及其相关注释将缓存在用于创建事务的会话中。当您调用提交时,您将导致会话中的所有对象被保存,从而导致保存回数据库。我不清楚它为什么要删除注释,但保存对象是正确的行为。

我也是stumbled upon this today

  

NHibernate正在删除我的全部内容   收集并重新创建它   更新表格。

     

这通常发生在NHibernate时   无法弄清楚哪些项目发生了变化   在集合中。常见原因是:

     
      
  • 完全用新的集合实例替换持久集合
  •   
  • 传递NHibernate手动构造的对象并在其上调用Update。
  •   
  • 序列化/反序列化持久性集合显然也会导致此问题。
  •   
  • 使用inverse =“false”更新a - 在这种情况下,NHibernate无法构造SQL来更新单个集合项。
  •   
     

因此,要避免这个问题:

     
      
  • 将您从NHibernate获得的同一个集合实例传回给它(不一定在同一个会话中),
  •   
  • 尝试使用其他一些集合代替(或)或
  •   
  • 尝试使用inverse =“true”属性。
  •   
相关问题