【问题标题】:NHibernate sql queries not actually taking effect on the databaseNHibernate sql 查询实际上并未对数据库生效
【发布时间】:2011-06-30 07:55:30
【问题描述】:

我在这里遇到了一些奇怪的问题,我无法调试。这个应用程序以前运行良好,但自从更改了休眠配置/sessoin 管理后,我以某种方式破坏了它,并且无法在哪里锻炼。

网页及其回帖似乎都可以正常工作,更改已保存到数据库中,什么都没有。事务/会话由我制作的 HTTPModule 处理:

 public class NHibernateSessionModule: IHttpModule
{
    private INHibernateRequest _nhibRequest;
    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(BeginTransaction);
        context.EndRequest += new EventHandler(CommitAndCloseSession);
        Console.WriteLine("Init Nhibernate module");
    }

    /// <summary>
    /// Opens a session within a transaction at the beginning of the HTTP request.
    /// This doesn't actually open a connection to the database until needed.
    /// </summary>
    private void BeginTransaction(object sender, EventArgs e)
    {
        _nhibRequest = new NHibernateRequest(NHibernateSessionManager.Instance);
        _nhibRequest.Start();
    }

    /// <summary>
    /// Commits and closes
    /// </summary>
    private void CommitAndCloseSession(object sender, EventArgs e)
    {
        _nhibRequest.Commit();
    }

    public void Dispose() { }
}

这个 INhibernateRequest 是我的一个自定义 DLl,它所做的只是:

 public class NHibernateRequest : INHibernateRequest
{
    private ITransaction _currentTransaction;
    private SessionFunctions _sessionFunctions;

    public NHibernateRequest(SessionFunctions sessionFunctions)
    {
        _sessionFunctions = sessionFunctions;
    }

    /// <summary>
    /// Starts a session and transaction
    /// </summary>
    public void Start()
    {
        _sessionFunctions.OpenSession();
        _currentTransaction = _sessionFunctions.CurrentSession.Transaction;
        _currentTransaction.Begin();
    }

    /// <summary>
    /// Closes a session and transaction
    /// </summary>
    public void Commit()
    {

        try
        {
            if (_currentTransaction.IsActive)
            {
                _currentTransaction.Commit();
            }
        }
        finally
        {
            _sessionFunctions.CloseSession();
        }



    }
}

基本会话管理。这一切似乎都适用于 .aspx 文件(Web 表单)。但是我有一个被调用的网络服务,它创建了一个新实体。我的领域模型专注于“表单”和“问题”,这个 Web 服务创建了一个带有一些问题的新表单。

我想也许这个 Web 服务没有触发处理程序,所以我手动输入了会话内容(是的,这有点狡猾,但它只是暂时的测试)

        [WebMethod]
    public bool CreateFormForProject(string jobNumber)
    {
        INHibernateRequest _nhibRequest = new NHibernateRequest(NHibernateSessionManager.Instance);
        _nhibRequest.Start();
        try
        {
            ServiceLayer.FormsService.CreatePmqccFormForJob(jobNumber);
            _nhibRequest.Commit();
            return true;
        } catch
        {
            _nhibRequest.Commit();
            return false;
        }
    }

Web 服务始终返回 true,因此不会引发异常。

然后我尝试在网页上制作一个按钮,该按钮进行此调用然后显示结果。这似乎创建了它,因为它显示了结果,但是当我刷新页面时,实体不再存在,并且它从未在数据库中,所以我猜它一定只是为该请求缓存了它。

所以我打开了 SQL 输出,并配置 log4net 将其吐出到调试输出窗口。这就是发生的事情:

 NHibernate.SQL: 17:45:59,466 DEBUG SQL:0 - SELECT project0_.ProjectNo as ProjectNo0_0_, project0_.Name1 as Name2_0_0_, project0_.Name2 as Name3_0_0_, project0_.Project_State as Project4_0_0_, project0_.ProjectLeader as ProjectL5_0_0_, project0_1_.AdminArchived as AdminArc2_2_0_ FROM infobase.dbo.Projects project0_ left outer join infobase.dbo.Project_Archiving project0_1_ on project0_.ProjectNo=project0_1_.ProjectNo WHERE project0_.ProjectNo=@p0;@p0 = '11904' [Type: String (4000)]
NHibernate.SQL: 17:45:59,692 DEBUG SQL:0 - UPDATE infobase.dbo.Projects SET Name1 = @p0, Name2 = @p1, Project_State = @p2, ProjectLeader = @p3 WHERE ProjectNo = @p4;@p0 = 'REVIT TO ACAD PREPARE AND EXPORT TOOL' [Type: String (4000)], @p1 = 'BIM SOLUTIONS API ADDIN' [Type: String (4000)], @p2 = Active [Type: Int32 (0)], @p3 = 187 [Type: Int32 (0)], @p4 = '11904' [Type: String (4000)]
NHibernate.SQL: 17:46:02,652 DEBUG SQL:0 - INSERT INTO Forms (LastSaved, Note, Complete, MeetingId, SuggestedDeferralMonth, NextReviewDate, LastReviewDate, SuggestedProjectState, SuggestedProjectLeader, ProjectId) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9); select SCOPE_IDENTITY();@p0 = 30/06/2011 5:46:02 PM [Type: DateTime (0)], @p1 = NULL [Type: String (4000)], @p2 = False [Type: Boolean (0)], @p3 = 0 [Type: Int32 (0)], @p4 = NULL [Type: Int32 (0)], @p5 = 30/06/2011 5:45:59 PM [Type: DateTime (0)], @p6 = NULL [Type: DateTime (0)], @p7 = NULL [Type: Int32 (0)], @p8 = NULL [Type: Int32 (0)], @p9 = '11904' [Type: String (4000)]
NHibernate.SQL: 17:46:02,735 DEBUG SQL:0 - INSERT INTO Questions (Explanation, PmqccFormId, InputtedAnswer, QuestionType) VALUES (@p0, @p1, @p2, 'PmqccDomain.DomainObjects.PiAlertQuestion'); select SCOPE_IDENTITY();@p0 = NULL [Type: String (4000)], @p1 = 8141 [Type: Int32 (0)], @p2 = Unanswered [Type: Int32 (0)]
NHibernate.SQL: 17:46:02,826 DEBUG SQL:0 - INSERT INTO Questions (Explanation, PmqccFormId, InputtedAnswer, QuestionType) VALUES (@p0, @p1, @p2, 'PmqccDomain.DomainObjects.ClientHappyQuestion'); select SCOPE_IDENTITY();@p0 = NULL [Type: String (4000)], @p1 = 8141 [Type: Int32 (0)], @p2 = Unanswered [Type: Int32 (0)]
NHibernate.SQL: 17:46:02,928 DEBUG SQL:0 - INSERT INTO Questions (Explanation, PmqccFormId, InputtedAnswer, QuestionType) VALUES (@p0, @p1, @p2, 'PmqccDomain.DomainObjects.ReworkQuestion'); select SCOPE_IDENTITY();@p0 = NULL [Type: String (4000)], @p1 = 8141 [Type: Int32 (0)], @p2 = Unanswered [Type: Int32 (0)]
NHibernate.SQL: 17:46:03,028 DEBUG SQL:0 - INSERT INTO Questions (Explanation, PmqccFormId, InputtedAnswer, QuestionType) VALUES (@p0, @p1, @p2, 'PmqccDomain.DomainObjects.ScopeOfWorksQuestion'); select SCOPE_IDENTITY();@p0 = NULL [Type: String (4000)], @p1 = 8141 [Type: Int32 (0)], @p2 = Unanswered [Type: Int32 (0)]
NHibernate.SQL: 17:46:03,130 DEBUG SQL:0 - INSERT INTO Questions (Explanation, PmqccFormId, InputtedAnswer, QuestionType) VALUES (@p0, @p1, @p2, 'PmqccDomain.DomainObjects.TeamMeetingQuestion'); select SCOPE_IDENTITY();@p0 = NULL [Type: String (4000)], @p1 = 8141 [Type: Int32 (0)], @p2 = Unanswered [Type: Int32 (0)]
NHibernate.SQL: 17:46:03,227 DEBUG SQL:0 - INSERT INTO Questions (Explanation, PmqccFormId, InputtedAnswer, QuestionType) VALUES (@p0, @p1, @p2, 'PmqccDomain.DomainObjects.DeadlinesQuestion'); select SCOPE_IDENTITY();@p0 = NULL [Type: String (4000)], @p1 = 8141 [Type: Int32 (0)], @p2 = Unanswered [Type: Int32 (0)]
NHibernate.SQL: 17:46:03,347 DEBUG SQL:0 - INSERT INTO Questions (Explanation, PmqccFormId, QuestionType) VALUES (@p0, @p1, 'PmqccDomain.DomainObjects.JobVelocityQuestion'); select SCOPE_IDENTITY();@p0 = NULL [Type: String (4000)], @p1 = 8141 [Type: Int32 (0)]
NHibernate.SQL: 17:46:03,433 DEBUG SQL:0 - INSERT INTO Questions (Explanation, PmqccFormId, InvoiceAmount, InputtedAnswer, QuestionType) VALUES (@p0, @p1, @p2, @p3, 'PmqccDomain.DomainObjects.InvoiceAmountQuestion'); select SCOPE_IDENTITY();@p0 = NULL [Type: String (4000)], @p1 = 8141 [Type: Int32 (0)], @p2 = NULL [Type: Double (0)], @p3 = Unanswered [Type: Int32 (0)]
NHibernate.SQL: 17:46:03,534 DEBUG SQL:0 - INSERT INTO Questions (Explanation, PmqccFormId, InputtedAnswer, QuestionType) VALUES (@p0, @p1, @p2, 'PmqccDomain.DomainObjects.InvoiceForecastQuestion'); select SCOPE_IDENTITY();@p0 = NULL [Type: String (4000)], @p1 = 8141 [Type: Int32 (0)], @p2 = Unanswered [Type: Int32 (0)]
NHibernate.SQL: 17:46:03,630 DEBUG SQL:0 - INSERT INTO Questions (Explanation, PmqccFormId, InputtedAnswer, QuestionType) VALUES (@p0, @p1, @p2, 'PmqccDomain.DomainObjects.ContactedClientQuestion'); select SCOPE_IDENTITY();@p0 = NULL [Type: String (4000)], @p1 = 8141 [Type: Int32 (0)], @p2 = NotRequired [Type: Int32 (0)]
NHibernate.SQL: 17:46:03,734 DEBUG SQL:0 - INSERT INTO Questions (Explanation, PmqccFormId, InputtedAnswer, QuestionType) VALUES (@p0, @p1, @p2, 'PmqccDomain.DomainObjects.AsConsQuestion'); select SCOPE_IDENTITY();@p0 = NULL [Type: String (4000)], @p1 = 8141 [Type: Int32 (0)], @p2 = NotRequired [Type: Int32 (0)]

这正是预期的结果,但数据库没有改变!!! SQL必须回滚或其他东西。我尝试在 _nhibRequest.Commit() 调用后设置断点,它表示事务已提交。

所以现在我很困惑,我该如何调试呢?或者任何人都可以看到我在这里做错了一些基本的事情吗?

编辑: 这是我发出 Web 服务请求时完整 log4net 调试输出的粘贴。 http://pastebin.com/mEYWiCsF

【问题讨论】:

  • 我的 NHibernate 知识有限,但是当身份列未在 ORM 定义或数据库表本身中正确设置/取消清除时,我看到了与 LINQ-to-SQL 类似的行为。 - 在您的 hbm 文件中,检查是否为您的问题表正确定义了 Identity 列?
  • 您说您做了一些更改,似乎“破坏”了您的代码。你能具体说明它们是什么吗?更好的是 - 您是否可以(暂时)回滚它们以查看其中哪些实际上破坏了您的应用程序?
  • 我基本上将我所有的 NHIbernate 特定代码重构为一个单独的 DLL,并从 hbm xml 文件转换为 Fluent 映射/配置。这通过了我们所有的测试,除了我们使用 Web 服务时。我做了更多的故障排除,似乎当我做与服务相同的事情时,在 aspx 页面加载时,它工作正常。我认为这可能与事务/会话上下文有关?但是,该代码并没有改变,并且在 Web 表单页面中一切正常。 .aspx 页面和我缺少的 asmx Web 服务之间有什么区别吗?
  • 这是我的日志输出.. 我看不到任何会说“哦,等等,不,我们实际上并没有将它放入数据库”....pastebin.com/mEYWiCsF

标签: c# asp.net nhibernate fluent-nhibernate


【解决方案1】:

我终于解决了。它实际上与这个 SO 问题有关: NHIbernate affecting non-nhibernate queries?

我解决这个问题的方法是提交并重新打开事务,这会导致这里出现问题。相反,我将其更改为冲洗,它似乎工作正常,但我很想为这个问题找到一个合适的解决方案。

【讨论】:

    猜你喜欢
    • 2015-12-18
    • 2011-05-23
    • 1970-01-01
    • 1970-01-01
    • 2013-10-17
    • 2020-08-11
    • 2020-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多