ahsteele
ahsteele

Reputation: 26514

NHibernate QuerySyntaxException

I am following along with the Summer of NHibernate Screencast Series and am running into a strange NHibernate Exception.

NHibernate.Hql.Ast.ANTLR.QuerySyntaxException:
Exception of type
'Antlr.Runtime.NoViableAltException' was thrown.
[select from DataTransfer.Person p where p.FirstName=:fn].

I have deviated from the Screencast Series in the following ways:

  1. Running against an MS SQL Server Compact Database
  2. I am using MSTest instead of MbUnit

I've tried any number of combination of queries always with the same result. My present CreateQuery syntax

public IList<Person> GetPersonsByFirstName(string firstName)
{
    ISession session = GetSession();

    return session.CreateQuery("select from Person p " +
        "where p.FirstName=:fn").SetString("fn", firstName)
        .List<Person>();
}

While not a direct query this method works

public Person GetPersonById(int personId)
{
    ISession session = GetSession();
    return session.Get<Person>(personId);
}

My hibernate.cfg.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory name="BookDb">
    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
    <property name="connection.driver_class">NHibernate.Driver.SqlServerCeDriver</property>
    <property name="dialect">NHibernate.Dialect.MsSqlCeDialect</property>
    <property name="connection.connection_string">Data Source=C:\Code\BookCollection\DataAccessLayer\BookCollectionDb.sdf</property>
    <property name="show_sql">true</property>
    <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
    <mapping assembly="DataTransfer"/>
  </session-factory>
</hibernate-configuration>

Person.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataTransfer" namespace="DataTransfer">
  <class name="DataTransfer.Person,DataTransfer" table="Person">
    <id name="PersonId" column="PersonId" type="Int32" unsaved-value="0">
      <generator class="native"/>
    </id>
    <property name="FirstName" column="FirstName" type="String" length="50" not-null="false" />
    <property name="LastName" column="LastName" type="String" length="50" not-null="false" />
  </class>
</hibernate-mapping>

Upvotes: 11

Views: 14817

Answers (2)

Leyu
Leyu

Reputation: 2687

I was also following the Summer of NHibernate Screencast Series and came across the same problem.

The problem is in the HQL "select from User p" change that to "select p from User p" or just "from User p".

The ’shorthand’ HQL form that was used in the screencasts under NHibernate version 1.2 was deprecated in 2.0 and eliminated in 2.1.x as the default query parser was switched out to be the more strict option.

public IList<Person> GetPersonsByFirstName(string firstName)
{
    ISession session = GetSession();

    return session.CreateQuery("select p from Person p where p.FirstName=:fn")
                              .SetString("fn", firstName)
                              .List<Person>();
}

Upvotes: 18

sirrocco
sirrocco

Reputation: 8055

Since you're specifying the namespace in the <hibernate-mapping element, you could write :

 <class name="Person" table="Person">
  ....

After you try that, if it doesn't work - I have no idea why it isn't working. I've tried pretty much the example you gave and it worked .

I have seen the new parser throw some weird errors and you just have to go by trial and error when it happens :(.

Edit

About the trial and error : you could change the query to "from Person" see if that works(if it doesn't...i'm stuck ) . Then add the filter, first try directly p.FirstName = 'x'. Then try with parameter. You could try not adding the alias.

Also, try using the latest version of NH.

Edit 2

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateTests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" namespace="NHibernateTests">

<class name="User" table="`User`" xmlns="urn:nhibernate-mapping-2.2">
<id name="Id" type="Int32" column="UserId">
  <generator class="assigned" />
</id>
<property name="UserName" type="String">
  <column name="UserName" not-null="true" />
</property>
<property name="FName" type="String">
  <column name="FName" />
</property>
  </class></hibernate-mapping>

and the query :

IList<User> users = session.CreateQuery("select from User p " +
                              "where p.UserName=:fn").SetString("fn", "u")
                  .List<User>();

Worked like a charm.

Upvotes: 5

Related Questions