2009-08-04 11 views
11

Estoy siguiendo junto con el Summer of NHibernate Screencast Series y me encuentro con una extraña excepción NHibernate.NHibernate QuerySyntaxException

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

he desviado de la Serie Screencast de las siguientes maneras:

  1. Correr contra una base de datos compacta MS SQL Server
  2. estoy usando MSTest en lugar de MbUnit

I Intenté cualquier combinación de consultas siempre con el mismo resultado. Mi sintaxis CreateQuery presente

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

Aunque no es una consulta directa este método funciona

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

Mi 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> 

Respuesta

18

Yo también estaba siguiendo el Summer of NHibernate Screencast Series y me encontré con el mismo problema.

El problema está en el HQL "seleccionar de usuario p" cambiarlo por "seleccione p de usuario p" o simplemente "de usuario p".

La forma HQL 'abreviada' que se utilizó en los screencasts bajo NHibernate versión 1.2 fue desuso en 2,0 y eliminado en 2.1.x como el analizador de consulta predeterminada se cambió a ser la opción más estricta .

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>(); 
} 
5

Puesto que usted está especificando el espacio de nombres en el elemento <hibernate-mapping, se podría escribir:

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

Después de probar que, si no funciona - no tengo ni idea de por qué no está funcionando. Intenté prácticamente el ejemplo que diste y funcionó.

he visto el nuevo analizador tirar algunos errores extraños y sólo hay que ir por ensayo y error cuando sucede :(

Editar

Sobre el ensayo y error:. Podría cambiar la consulta para "de Persona" ver si eso funciona (si no ... estoy atascado). Luego agregue el filtro, primero intente directamente p.FirstName = 'x'. Luego pruebe con el parámetro. Podría intentarlo sin agregar el alias.

Además, intente utilizar la última versión de NH

Editar 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> 

y la consulta:

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

funcionó de maravilla.

+0

hizo el cambio a * * Person.hbm.xml en vano. Usted indica que la prueba y el error es una forma de resolver los extraños errores del analizador de NHibernate, ¿qué tipo de pruebas debo hacer? – ahsteele

+0

Seleccionado cambiado para simplemente "seleccionar de DataTransfer.Person p" y recibido el mismo error. Estoy usando Build 2.1.0 de NHibernate. ¿Estás usando una base de datos MS SQL Server Compact? La única otra diferencia que puedo ver entre nuestro trabajo es que está siendo más explícito sobre el ensamblado NHibernateTests en * User.hbm.xml *. ¿Otros pensamientos? – ahsteele

+1

¿Intentó dejar el seleccionar solo: "de Persona" (es legítimo en hql)? En realidad estoy probando contra sqlite pero dudo que importe ya que el analizador antlr trabaja para generar la consulta y si la base de datos era el problema, obtendría una sqlexception – sirrocco