views:

1976

answers:

4

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>
+2  A: 

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.

sirrocco
Made the change to *Person.hbm.xml* to no avail. You indicate that trial and error is a way to work through weird NHibernate parser errors, what sort of trials should I be doing?
ahsteele
Changed select to simply "select from DataTransfer.Person p" and received same error. I am using Build 2.1.0 of NHibernate. Are you using a MS SQL Server Compact Database? The only other difference I can see between our work is that you are being more explicit about the NHibernateTests assembly in *User.hbm.xml*. Other thoughts?
ahsteele
did you try leaving the select just : "from Person"(it's legitimate in hql) ? I'm actually testing against sqlite but I doubt it matters as the antlr parser works towards generating the query and if the database was the problem you would get an sqlexception
sirrocco
and no, the explicit assembly is not causing this.
sirrocco
didn't realize you meant just "from person p". That totally worked, what's the deal? Figured it wasn't the assembly but thought I'd mention it.
ahsteele
wait, so it works with the filter too ? WOHOO :). Not sure what the problem was, again, you can see the query I tested and worked ... so, not sure. You could also ask on the nhusers group on google. They might have more detail.
sirrocco
+6  A: 

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>();
}
Leyu
A: 

The answer from Leyu worked for me. I had the same problem and the change in the HQL is the answer.

Joe
A: 

thank a lot Leyu ..

Mohammadk