2009-08-04 9 views
11

Podążam wraz z Summer of NHibernate Screencast Series i mam uruchomiony dziwny wyjątek 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]. 

Mam odbiegała od serii screencast w jeden z następujących sposobów:

  1. Running przeciwko Compact bazy danych MS SQL Server
  2. używam MSTest zamiast MbUnit

I Wypróbowaliśmy dowolną liczbę kombinacji zapytań zawsze z tym samym wynikiem. Mój obecny składnia CreateQuery

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

Choć nie jest to bezpośrednia metoda ta kwerenda działa

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

mój 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> 

Odpowiedz

18

Podążałem także za Summer of NHibernate Screencast Series i natrafiłem na ten sam problem.

Problem jest w HQL „wybrać od użytkownika p” zmienić na „Wybierz P od użytkownika p” lub po prostu „od użytkownika p”.

do „skrótem” forma HQL, który został użyty w screencasts pod NHibernate wersji 1.2 był przestarzałe w 2,0 i wyeliminowane w 2.1.x jako domyślny parser zapytanie zostało włączone się być bardziej rygorystyczne opcja .

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

Skoro określaniem przestrzeni nazw w elemencie <hibernate-mapping, można napisać:

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

Po próbie, że jeśli to nie działa - nie mam pojęcia, dlaczego to nie działa. Próbowałem prawie tego samego przykładu, który dałeś i działało.

Widziałem nowy parser rzucać jakieś dziwne błędy i po prostu trzeba iść metodą prób i błędów, gdy to się dzieje :(

Edycja

O prób i błędów. Można zmienić zapytanie do "od osoby" zobaczyć, czy to działa (jeśli nie ... utknąłem) .Dodaj filtr, najpierw spróbuj bezpośrednio p.FirstName = "x." Następnie spróbuj z parametrem. nie dodawanie pseudonimu

Spróbuj również użyć najnowszej wersji NH.

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

i zapytania:

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

Pracował jak czar.

+0

wprowadził zmianę do * Person.hbm.xml * bezskutecznie. Wskazujesz, że próba i błąd to sposób na pracę z dziwnymi błędami parserów NHibernate, jakie testy powinienem wykonywać? – ahsteele

+0

Zmieniono wybór, aby po prostu "wybrać z DataTransfer.Person p" i otrzymano ten sam błąd. Używam Build 2.1.0 NHibernate. Czy korzystasz z kompaktowej bazy danych MS SQL Server? Jedyną inną różnicą, jaką widzę pomiędzy naszą pracą, jest to, że wyraźnie mówisz o zestawie NHibernateTests w pliku * User.hbm.xml *. Inne przemyślenia? – ahsteele

+1

próbowałeś pozostawiając wybór just: "from Person" (jest to uzasadnione w hql)? Właściwie testuję przeciwko sqlite, ale wątpię, aby miało to znaczenie, ponieważ parser antlr działa w kierunku generowania zapytania i jeśli baza danych byłaby problemem, dostaniesz sqlexception – sirrocco