3

首先是映射,

<set name="Comments" table="cm_events_venue_comment" inverse="true"
        lazy="true" generic="true" cascade="all-delete-orphan"
        batch-size="10" order-by="dateCreated ASC">
    <cache usage="read-write" />
    <key column="venueId" />
    <one-to-many class="VenueComment" />
</set>

一次通过测试,

[Test]
public void CanSaveAndDeleteComments()
{
    User u = TestDataHelper.CreateUser("Sir", "Talkalot");
    VenueComment comment;
    Venue v = GetVenueById();

    PerformInTransaction(() =>
    {
        userRepository.SaveOrUpdate(u);
        comment = new VenueComment()
        {
            Commenter = u,
            Text = "I like ifs and buts and i cannot lie..",
            DateCreated = DateTime.Now
        };
        v.AddComment(comment);
        comment = new VenueComment()
        {
            Commenter = u,
            Text = "And words ending in 'ly'",
            DateCreated = DateTime.Now
        };
        v.AddComment(comment);
        Assert.DoesNotThrow(()=>venueRepository.SaveOrUpdate(v));
    });

    // Test retrieval 
    Session.Evict(v);

    v = GetVenueById();
    v.Comments.Count.ShouldEqual(2);
    var c = v.Comments.FirstOrDefault<VenueComment>();
    c.Commenter.Id.ShouldEqual(u.Id);

    // and deletion
    PerformInTransaction(() =>
    {
        v.RemoveComment(c);
    });

    Session.Evict(v);
    v = GetVenueById();
    v.Comments.Count.ShouldEqual(1);

}

我的问题出现在我的应用程序的控制器中,

[Authenticate, AcceptAjax]
public ActionResult DeleteComment(int id)
{
    return PerformInTransaction<ActionResult>(() =>
        {
            var comment = commonDao.GetObjectById<VenueComment>(id);
            if (comment == null)
                return JsonFailure("Comment not found");

            if (comment.Commenter.Id == CurrentUser.Id ||
                AuthUtil.IsAdministrator()) //
            {

               var venue = comment.Venue;
               venue.RemoveComment(comment);

                return JsonSuccess(id);
            }
            return JsonFailure("You can only delete comments you created.");
        });
}

根据 Log4Net,没有发布任何删除。正如我所说,上面的测试通过了,所以映射应该是正确的。

有什么线索吗?

4

3 回答 3

5

如果您查看inverse有关集合类型属性映射的属性的文档,您会发现该设置inverse="false"指示 NHibernate 监视父对象(包含集合的对象)对集合的更改,并插入/删除子对象基于父子集合的添加/删除。

但是,当您设置 时inverse="true",您是在指示 NHibernate 监视子对象,将引用属性更改回父对象。所以当你设置孩子的父引用属性时,NHibernate 会去修改关联。

看起来您不想设置inverse="true"父级的子级集合。

附录:

RemoveComment可能会解除父级与子级的关联(如 set child.Parent = null)。但是,如果它也没有解除子节点与 的关联Session,并且如果集合被标记为inverse="true"指示子节点拥有关联而不是集合拥有关联,那么 NHibernate 将不会发送 a delete。NHibernate 只会delete在对象应该被删除的情况下发送 a) - a) 如果集合拥有关联 ( inverse="false") 并且集合的级联设置为包括删除并且从集合中删除对象,或者 b) 如果对象是从Session.

于 2009-10-26T02:10:59.677 回答
1

谜团解开了……这是一个合并两个代码库的案例……

一个较旧的 dao (commonDao) 有一个错误,即内部 Session 属性在每次属性访问时从会话工厂创建一个新会话,因此对象加载和 flush() 之间存在不同的会话。

较新的代码使用基于 S#arp 架构的存储库,它具有自动会话管理,因此问题没有出现在单元测试中。

于 2009-10-26T06:16:58.370 回答
1

根据我的经验,当我忘记提交事务或正确关闭并刷新会话时,就会发生这种情况。会话和事务管理也是您的测试和演示者之间的显着区别。

于 2009-10-26T02:00:48.573 回答