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

コレクション型のプロパティ マッピングに関する属性のドキュメントを参照すると、コレクションへの変更について親オブジェクト (コレクションを含むオブジェクト) を監視し、子オブジェクトを挿入/削除するように NHibernate に指示inverseする設定であることがわかります。inverse="false"親の子コレクションの追加/削除に基づいています。

しかし、 を設定inverse="true"すると、親オブジェクトへの参照プロパティへの変更を子オブジェクトで監視するよう NHibernate に指示することになります。したがって、子の親参照プロパティを設定すると、NHibernate は関連付けを変更します。

inverse="true"親の子コレクションに設定したくないようです。

補遺:

RemoveComment親と子の関連付けを解除できます ( set のようにchild.Parent = null)。しかし、子と の関連付けを解除せず、コレクションが関連付けを所有しているコレクションではなく子が関連付けを所有していることを示すSessionようにコレクションがマークされている場合、NHibernate は を送信しません。NHibernate は、オブジェクトが削除されることになっている場合にのみ a を送信します - a) コレクションが関連付け ( ) を所有し、コレクションのカスケードが削除を含むように設定されていて、オブジェクトがコレクションから削除された場合、または b) オブジェクトがから削除されました。inverse="true"deletedeleteinverse="false"Session

于 2009-10-26T02:10:59.677 に答える
1

私の経験では、これは、トランザクションをコミットするか、セッションを適切に閉じてフラッシュするのを忘れたときに発生します。セッションとトランザクションの管理も、テストとプレゼンターの顕著な違いです。

于 2009-10-26T02:00:48.573 に答える
1

Mystery Solved.... それは 2 つのコード ベースのマージのケースでした..

1 つの古い dao (commonDao) には、内部の Session プロパティがプロパティ アクセスごとにセッション ファクトリから新しいセッションを作成するというバグがあったため、オブジェクトのロードと flush() の間に異なるセッションがありました。

新しいコードは、自動セッション管理を備えた S#arp アーキテクチャに基づくリポジトリを使用しているため、単体テストでは問題は発生しませんでした。

于 2009-10-26T06:16:58.370 に答える