NHibernate 2nd lvl cache, custom query, sqldialect

前端 未结 7 1061
遥遥无期
遥遥无期 2020-12-21 06:59

I got trunk version of NH and FNH. When i try to add 2nd level cache, some parts of NHibernate forgets about chosen sqldialect.


Initial configuration:

相关标签:
7条回答
  • 2020-12-21 07:28

    I encountered this problem when upgrading from 1.2 to 3.2 (I know, BIG jump eh?).

    The issue in my case was that there is a leading space in front of the select statement in the hql, e.g. String hql = " select "...

    With SQL2005 Dialect, this crashes with a "System.NotSupportedException: The query should start with 'SELECT'..." message.

    The solution is to

    1. create a unit test that fails, a good Test Driven Developer should :)
    2. remove the leading space from the " select..." statement
    3. build and run the unit test
    0 讨论(0)
  • 2020-12-21 07:28

    Just as i predicted - unbounding select is acceptable workaround.

    Deleted SetMaxResults and it works.

    0 讨论(0)
  • 2020-12-21 07:33

    It seems that there is some strange bug in the routine used to find the place in the query to insert the TOP clause (GetAfterSelectInsertPoint ) as told by Sandor. You can fix it directly in nh source (I actually patched 2.1 version I'm using in a project, you can find details here). So if you absolutely needs to enable comments with use_sql_comments you can :)

    0 讨论(0)
  • 2020-12-21 07:42

    We ran into this issue when upgrading to NHibernate version 3.3, but for a different reason...whitespace. We had a lot of sql strings that looked like this:

    var sql = @"
    select col1 from MyTable";
    

    or:

    var sql = @" select col1 from My Table";
    

    These resulted in the "The query should start with 'SELECT' or 'SELECT DISTINCT'" errors because NHibernate doesn't trim the string before validating it.

    We created a new dialect that trims the string first to get around this:

    public class Sql2008DialectCustom : MsSql2008Dialect
    {
      public override SqlString GetLimitString(SqlString queryString, SqlString offset, SqlString limit)
      {
        var trimmedQueryString = queryString.Trim();
        return base.GetLimitString(trimmedQueryString, offset, limit);
      }
    }
    
    0 讨论(0)
  • 2020-12-21 07:45

    I had a similar issue (removing SetMaxResults also helped but I needed paging) and found out that the following NHibernate configuration property was causing this bug:

    <property name="use_sql_comments">true</property>
    

    It's certainly a bug, because the GetAfterSelectInsertPoint method doesn't take into account that SQL comments may be prepended to the SQL query.

    Just set the use_sql_comments property to false and the problem disappears.

    0 讨论(0)
  • 2020-12-21 07:45

    I repaired the bug using Alkampfer's solution, but I created my own SQL dialect rather than patching the NHibernate source directly:

    public class Sql2008DialectWithBugFixes : MsSql2008Dialect
    {
        public override SqlString GetLimitString(SqlString querySqlString, int offset, int last)
        {
            if (offset == 0)
            {
                return querySqlString.Insert(GetAfterSelectInsertPoint(querySqlString), " top " + last);
            }
    
            return base.GetLimitString(querySqlString, offset, last);
        }
    
        private static int GetAfterSelectInsertPoint(SqlString sql)
        {
            Int32 selectPosition;
    
            if ((selectPosition = sql.IndexOfCaseInsensitive("select distinct")) >= 0)
            {
                return selectPosition + 15; // "select distinct".Length;
    
            }
            if ((selectPosition = sql.IndexOfCaseInsensitive("select")) >= 0)
            {
                return selectPosition + 6; // "select".Length;
            }
    
            throw new NotSupportedException("The query should start with 'SELECT' or 'SELECT DISTINCT'");
        }
    }
    
    0 讨论(0)
提交回复
热议问题