1

初めてオブジェクトに対して get を呼び出すと、クロス データベース オブジェクトは完全にハイドレートされます。ただし、オブジェクトを保存すると、CreateUser と UpdateUser が null になります。OriginalNote 参照は常に機能します (そして、CreateUser は null ではありません)。オブジェクト グラフ全体を再作成するために、保存後に新しい ID を取得しようとしています。元のメモの最初の Get はうまく機能しますが、保存したばかりのオブジェクトに入力するものは機能しません。

マッピング:

public sealed class DocumentNoteMap : EntityMapBase<DocumentNote>
{
    public DocumentNoteMap()
    {
        Table("DocDataNote");
        Id(x => x.DocDataNoteID).GeneratedBy.Native().UnsavedValue(null);

        Map(x => x.DocDataID);
        Map(x => x.DocDataEventID);
        Map(x => x.NoteText).Column("Note");
        References(x => x.OriginalNote).Class<DocumentNote>().Column("ParentDocDataNoteID")
            .Not.LazyLoad()
            .Not.Update();

        References(x => x.UpdateUser).Class<CasUser>().Column("UpdateBy")
            .ReadOnly()
            .Not.LazyLoad()
            .Not.Update();
        References(x => x.CreateUser).Class<CasUser>().Column("CreateBy")
            .ReadOnly()
            .Not.LazyLoad()
            .Not.Update();
    }

public class CasUserMap : ClassMap<CasUser>
{
    public CasUserMap()
    {
        Schema("CAS.dbo");
        Table("CAS_User");
        Id(x => x.CASUserID);

        Map(x => x.FirstName);
        Map(x => x.LastName);
    }
}

DocumentNoteRepository:

[Repository]
public class DocumentNoteRepository : HibernateRepositoryBase<DocumentNote,int?>, IDocumentNoteRepository
{
    public DocumentNoteRepository(ISessionFactory sessionFactory)
        :base(sessionFactory)
    {

    }

    public int? Save(DocumentNote entity, bool autoFlush)
    {
        var persisted = (DocumentNote)CurrentSession.Merge(entity);
        entity.DocDataNoteID = persisted.DocDataNoteID;
        if (autoFlush) { CurrentSession.Flush(); }

        return entity.DocDataNoteID;
    }
}

get メソッドは基本クラスにあります。

/// <summary>
/// Base class for data access operations.
/// </summary>
public abstract class HibernateRepositoryBase<TEntity, TId> : IRepository<TEntity, TId> where TEntity : class
{
    private ISessionFactory _sessionFactory;

    public IQueryable<TEntity> Query()
    {
        return CurrentSession.Query<TEntity>();
    }
    protected HibernateRepositoryBase(ISessionFactory sessionFactory)
    {
        _sessionFactory = sessionFactory;

    }

    /// <summary>
    /// Session factory for sub-classes.
    /// </summary>
    protected ISessionFactory SessionFactory
    {
        get { return _sessionFactory; }
        private set { _sessionFactory = value; }
    }

    /// <summary>
    /// Get's the current active session. Will retrieve session as managed by the 
    /// Open Session In View module if enabled.
    /// </summary>
    protected ISession CurrentSession
    {
        get
        {
            var session = _sessionFactory.GetCurrentSession();
            _sessionFactory.GetCurrentSession().EnableFilter("TenantFilter").SetParameter("TenantID", User.Current.OrganizationId);
            return session;
        }
    }


    [Transaction(ReadOnly = true)]
    public TEntity Get(TId id)
    {

        var entity=CurrentSession.Get<TEntity>(id);
        if (entity == null)
        {
            throw new DataException("Could not find entity of Type{0} and Primary Key {1}".FormatWith(typeof(TEntity), id.ToString()));   
        }
        // evict so changes don't get inadvertently persisted
        //CurrentSession.Evict(entity);

        return entity;
    }
    [Transaction(ReadOnly = true)]
    public IList<TEntity> GetAll()
    {
        var listOfEntities = CurrentSession.CreateCriteria<TEntity>().List<TEntity>();

        // evict so changes don't get inadvertently persisted - can change when OSIV is removed
        listOfEntities.ToList().ForEach(e => CurrentSession.Evict(e));

        return listOfEntities;
    }
}

編集:

私が試したこと:
1.保存後(取得前)にフラッシュを強制しようとしました。
2. 保存後 (取得前) に保存されたオブジェクトを削除する

4

1 に答える 1

0

私の問題を見つけました。オブジェクトを削除しようとしたときに、間違ったオブジェクトを削除していました。NHibernate が Merge で返したオブジェクト (持続) ではなく、マージしていたオブジェクト (エンティティ) を削除していました。

(以下に示すように) マージから返された永続化されたオブジェクトを削除すると、問題が解決しました。

    public int? Save(DocumentNote entity, bool autoFlush)
    {
        var persisted = (DocumentNote)CurrentSession.Merge(entity);
        entity.DocDataNoteID = persisted.DocDataNoteID;
        if (autoFlush)
        {
            CurrentSession.Flush();
            CurrentSession.Evict(persisted);
        }

        return entity.DocDataNoteID;
    }
于 2012-10-02T14:23:41.880 に答える