2009-08-04 23 views
11

Tôi đang theo dõi cùng với Summer of NHibernate Screencast Series và đang chạy vào Ngoại lệ NHibernate lạ.NHibernate QuerySyntaxException

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

Tôi đã chệch khỏi các Screencast Series trong các cách sau:

  1. Chạy chống lại một cơ sở dữ liệu nhỏ gọn MS SQL Server
  2. Tôi đang sử dụng MSTest thay vì MbUnit

tôi đã thử mọi kết hợp truy vấn luôn với cùng một kết quả. cú pháp CreateQuery hiện tại của tôi

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

Trong khi không phải là một truy vấn trực tiếp Phương pháp này hoạt động

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> 

Trả lời

18

Tôi cũng đang theo dõi Summer of NHibernate Screencast Series và gặp phải vấn đề tương tự.

Vấn đề là trong HQL "chọn từ tài khoản p" thay đổi điều đó để "chọn p từ tài khoản p" hay chỉ "từ tài khoản p".

Các 'tốc ký' HQL hình thức được sử dụng trong các Screencasts dưới NHibernate phiên bản 1.2 là phản trong 2.0 và loại bỏ trong 2.1.x như phân tích cú pháp truy vấn mặc định đã được bật ra được sự lựa chọn khắt khe hơn .

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

Vì bạn đang xác định không gian tên trong thành phần <hibernate-mapping, bạn có thể viết:

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

Sau khi bạn cố gắng đó, nếu nó không hoạt động - Tôi không có ý tưởng tại sao nó không được làm việc. Tôi đã thử khá nhiều ví dụ bạn đã cho và nó đã làm việc.

Tôi đã thấy các phân tích cú pháp mới ném một số lỗi lạ và bạn chỉ phải đi bằng cách thử và sai khi nó xảy ra :(

Sửa

Giới thiệu về dùng thử và báo lỗi:. Bạn có thể thay đổi truy vấn để "từ người" xem nếu điều đó hoạt động (nếu nó không ... tôi đang bị mắc kẹt). Sau đó thêm bộ lọc, đầu tiên hãy thử trực tiếp p.FirstName = 'x'. Sau đó thử với tham số. Bạn có thể thử không thêm bí danh.

Ngoài ra, hãy thử sử dụng phiên bản mới nhất của NH.

Chỉnh sửa 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> 

và truy vấn:

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

Làm việc như một nét duyên dáng.

+0

Thực hiện thay đổi thành * Person.hbm.xml * thành không có. Bạn chỉ ra rằng dùng thử và lỗi là một cách để làm việc thông qua các lỗi phân tích cú pháp NHibernate lạ, tôi nên làm những loại thử nghiệm nào? – ahsteele

+0

Thay đổi chọn đơn giản là "chọn từ DataTransfer.Person p" và nhận được lỗi tương tự. Tôi đang sử dụng Build 2.1.0 của NHibernate. Bạn đang sử dụng MS SQL Server Compact Database? Sự khác biệt duy nhất tôi có thể thấy giữa công việc của chúng tôi là bạn đang được rõ ràng hơn về lắp ráp NHibernateTests trong * User.hbm.xml *. Suy nghĩ khác? – ahsteele

+1

bạn đã thử để lại lựa chọn chỉ: "từ người" (đó là hợp pháp trong hql)? Tôi thực sự thử nghiệm đối với sqlite nhưng tôi nghi ngờ nó quan trọng khi trình phân tích cú pháp antlr hoạt động hướng tới việc tạo truy vấn và nếu cơ sở dữ liệu là vấn đề bạn sẽ nhận được một sqlexception – sirrocco