代码之家  ›  专栏  ›  技术社区  ›  Roman

使用nhibernate在插入后立即查询时出现不正确的组件

  •  1
  • Roman  · 技术社区  · 14 年前

    我在mysql中的表有以下映射:

    <class name="Tag, namespace" table="tags" >
     <id name="id" type="Int32" unsaved-value="0">
       <generator class="native"></generator>
     </id>
     <property name="name" type="String" not-null="true"></property>
     <component name="record_dates" class="DateMetaData, namespace" >
       <property name="created_at" type="DateTime" not-null="true"></property>
       <property name="updated_at" type="DateTime" not-null="true"></property>
     </component>
    </class>
    

    如您所见,record_dates属性被定义为datemetadate类型的组件字段。“标记”表中的“创建位置”和“更新位置”字段都通过触发器更新。因此,我可以插入这样的新记录:

    var newTag = new Tag() 
    { 
     name = "some string here"
    }
    
    Int32 id = (Int32)Session.Save(tag);
    Session.Flush();
    
    ITag t = Session.Get<Tag>(id);
    ViewData["xxx"] = t.name; // -----> not null
    ViewData["xxx"] = t.record_dates.created_at; // -----> is null
    

    但是,当在插入同一条记录后立即将其查询回来时, record_dates 字段最终为空,即使在表中这些字段有值。

    有人能指出为什么 Session.Get 忽略从桌子上拿回来的东西?是因为它缓存了记录日期为空的新创建的记录吗?如果是这样,怎么能告诉它忽略缓存的版本?

    3 回复  |  直到 14 年前
        1
  •  0
  •   Prashant    14 年前

    尝试在类标记中使用lazy=“false”:

    <class name="Tag, namespace" table="tags" lazy="false">
    

    据我所知,默认行为是延迟加载,这可能不会根据需要刷新对象。

        2
  •  0
  •   Roman    14 年前

    到目前为止我唯一找到的就是打电话 Session.Clear() 方法,我猜该方法会强制nhibernate再次从表中获取记录。但我担心它会删除缓存中的所有内容,因此效率低下。

        3
  •  0
  •   Jamie Ide    14 年前

    你可以打电话 ISession.Refresh(obj) 强制从数据库重新加载对象。我的理解是,这不会刷新所有关系,因此如果需要重新加载完整的对象图,请调用 ISession.Evict(obj) 然后 ISession.Get(id) 将其从缓存中移除并重新加载。