2009-08-04 9 views
11

Ich bin zusammen mit der Summer of NHibernate Screencast Series gefolgt und bin in eine seltsame NHibernate Exception.NHibernate QuerySyntaxException

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

Ich habe von der Screen Serie auf folgende Weise abgewichen:

  1. Rennen gegen eine MS SQL Server Compact-Datenbank
  2. ich MSTest bin mit statt MbUnit

I habe eine beliebige Kombination von Abfragen immer mit dem gleichen Ergebnis versucht. Meine gegenwärtige Create 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>(); 
} 

Während keine direkte Abfrage funktioniert diese Methode

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

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

Antwort

18

Ich folgte auch die Summer of NHibernate Screencast Series und stieß auf das gleiche Problem.

Das Problem ist in den HQL "aus User p", die auf "select p von Benutzer p" oder "von User-p" nur ändern.

Die ‚Kurzschrift‘ HQL Form, die 1,2 war in 2.0 als veraltet in den Screencasts unter NHibernate Version verwendet wurde und eliminierten in 2.1.x als der Parser Standardabfrage die strenge Option sein schaltet wurde aus .

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

Da Sie den Namensraum im <hibernate-mapping Element sind spezifizieren, könnten Sie schreiben:

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

Nachdem Sie versuchen, dass, wenn es nicht funktioniert - ich habe keine Ahnung, warum es nicht funktioniert. Ich habe das Beispiel, das du gegeben hast, ausprobiert und es hat funktioniert.

Ich habe der neue Parser einige seltsamen Fehler und du nur gehen, um durch Versuch und Irrtum, wenn es :(passiert

bearbeiten

über den Versuch und Irrtum wirft gesehen. Sie ändern könnten die Abfrage auf "von Person" sehen, ob das funktioniert (wenn es nicht ... ich bin stecken). Dann fügen Sie den Filter, zuerst versuchen Sie direkt p.FirstName = 'x'. Dann versuchen Sie mit Parameter. Sie könnten versuchen

Verwenden Sie auch die neueste Version von NH

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

und die Abfrage:

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

wie ein Charme.

+0

die Änderung * Person.hbm.xml * ohne Erfolg gemacht. Sie zeigen an, dass Trial and Error eine Möglichkeit ist, durch seltsame NHibernate-Parser-Fehler zu arbeiten. Welche Art von Tests sollte ich durchführen? – ahsteele

+0

Geändert, um einfach "aus DataTransfer.Person p auszuwählen" und denselben Fehler erhalten. Ich benutze Build 2.1.0 von NHibernate. Verwenden Sie eine MS SQL Server Compact-Datenbank? Der einzige andere Unterschied, den ich zwischen unseren Arbeiten sehen kann, ist, dass Sie bezüglich der NHibernateTests-Assemblierung in * User.hbm.xml * expliziter sind. Andere Gedanken? – ahsteele

+1

haben Sie versucht, die Auswahl nur: "von Person" (es ist legitim in HQ) verlassen? Ich teste tatsächlich gegen sqlite, aber ich bezweifle, dass es wichtig ist, da der antlr-Parser auf die Generierung der Abfrage hinarbeitet und wenn die Datenbank das Problem wäre, würden Sie eine sqlexception – sirrocco