开发者

How to tell the Session to throw the error query[NHibernate]?

I made a test class against the repository methods shown below:

        public void AddFile<TFileType>(TFileType FileToAdd) where TFileType : File
  {
   try
   {
    _session.Save(FileToAdd);
    _session.Flush();
   }
   catch (Exception e)
   {
    if (e.InnerException.Message.Contains("Violation of UNIQUE KEY"))
     throw new ArgumentException("Unique Name must be unique");
    else
     throw e;
   }
  }

        public void RemoveFile(File FileToRemove)
  {
   _session.Delete(FileToRemove);
   _session.Flush();
  }

And the test class:

            try
   {
    Data.File crashFile = new Data.File();
    crashFile.UniqueName = "NonUniqueFileNameTest";
    crashFile.Extension = ".abc";
    repo.AddFile(crashFile);
    Assert.Fail();
   }
   catch (Exception e)
   {
    Assert.IsInstanceOfType(e, typeof(ArgumentException));
   }

   // Clean up the file
   Data.File removeFile = repo.GetFiles().Where(f => f.UniqueName == "NonUniqueFileNameTest").FirstOrDefault();
   repo.RemoveFile(removeFile);

The test fails. When I step in to trace the problem, I found out that when I do the _session.flush() right after _session.delete(), it throws the exception, and if I look at the sql it does, it is actually submitting a "INSERT INTO" statement, which is exactly the sql that cause UNIQUE CONSTRAINT error. I tried to encapsulate both in transaction but still same problem happens. Anyone know the reason?


Edit

The other stay the same, only added Evict as suggested

        public void AddFile<TFileType>(TFileType FileToAdd) where TFileType : File
  {
   try
   {
    _session.Save(FileToAdd);
    _session.Flush();
   }
   catch (Exception e)
   {
   _session.Evict(FileToAdd);
    if (e.InnerException.Message.Contains("Violation of UNIQUE KEY"))
     throw new ArgumentException("Unique Name must be unique");
    else
     throw e;
   }
  }
开发者_如何学C

No difference to the result.


Call _session.Evict(FileToAdd) in the catch block. Although the save fails, FileToAdd is still a transient object in the session and NH will attempt to persist (insert) it the next time the session is flushed.


NHibernate Manual "Best practices" Chapter 22:

This is more of a necessary practice than a "best" practice. When an exception occurs, roll back the ITransaction and close the ISession. If you don't, NHibernate can't guarantee that in-memory state accurately represents persistent state. As a special case of this, do not use ISession.Load() to determine if an instance with the given identifier exists on the database; use Get() or a query instead.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜