2011-11-22 216 views
45

我一直在玩一個非常簡單的JPA示例,並試圖將其調整到現有的數據庫。但我無法克服這個錯誤。 (下面)這只是一些簡單的事情,我沒有看到。JPA映射:「QuerySyntaxException:foobar未映射...」

org.hibernate.hql.internal.ast.QuerySyntaxException: FooBar is not mapped [SELECT r FROM FooBar r] 
    org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:180) 
    org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:110) 
    org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:93) 

在下面的DocumentManager類(一個簡單的servlet,因爲這是我的目標的目標)做了兩兩件事:

  1. 插入一行
  2. 返回所有行

的插入工作完美 - 一切都很好。問題在於檢索。我已經嘗試了Query q = entityManager.createQuery參數的各種值,但沒有運氣,並且我嘗試了各種更明確的類註解(如列類型),都沒有成功。

請從我身邊救我。我敢肯定,這是小事。我對JPA的經驗不足使我無法繼續前進。

我./src/ch/geekomatic/jpa/FooBar.java文件:

@Entity 
@Table(name = "foobar") 
public class FooBar { 
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    @Column(name="id") 
    private int id; 

    @Column(name="rcpt_who") 
    private String rcpt_who; 

    @Column(name="rcpt_what") 
    private String rcpt_what; 

    @Column(name="rcpt_where") 
    private String rcpt_where; 

    public int getId() { 
     return id; 
    } 
    public void setId(int id) { 
     this.id = id; 
    } 

    public String getRcpt_who() { 
     return rcpt_who; 
    } 
    public void setRcpt_who(String rcpt_who) { 
     this.rcpt_who = rcpt_who; 
    } 

    //snip...the other getters/setters are here 
} 

我./src/ch/geekomatic/jpa/DocumentManager.java類

public class DocumentManager extends HttpServlet { 
    private EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("ch.geekomatic.jpa"); 

    protected void tearDown() throws Exception { 
     entityManagerFactory.close(); 
    } 

    @Override 
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 
     FooBar document = new FooBar(); 
     document.setRcpt_what("my what"); 
     document.setRcpt_who("my who"); 

     persist(document); 

     retrieveAll(response); 
    } 

    public void persist(FooBar document) { 
     EntityManager entityManager = entityManagerFactory.createEntityManager(); 
     entityManager.getTransaction().begin(); 
     entityManager.persist(document); 
     entityManager.getTransaction().commit(); 
     entityManager.close(); 
    } 

    public void retrieveAll(HttpServletResponse response) throws IOException { 
     EntityManager entityManager = entityManagerFactory.createEntityManager(); 
     entityManager.getTransaction().begin(); 

     // *** PROBLEM LINE *** 
     Query q = entityManager.createQuery("SELECT r FROM foobar r", FooBar.class); 
     List<FooBar> result = q.getResultList(); 

     for (FooBar doc : result) { 
      response.getOutputStream().write(event.toString().getBytes()); 
      System.out.println("Document " + doc.getId() ); 
     } 
     entityManager.getTransaction().commit(); 
     entityManager.close(); 
    } 
} 

的{Tomcat的家} /webapps/ROOT/WEB-INF/classes/METE-INF/persistance.xml文件

<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" 
    version="2.0"> 

<persistence-unit name="ch.geekomatic.jpa"> 
    <description>test stuff for dc</description> 

    <class>ch.geekomatic.jpa.FooBar</class> 

    <properties> 
     <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /> 
     <property name="javax.persistence.jdbc.url"  value="jdbc:mysql://svr:3306/test" /> 
     <property name="javax.persistence.jdbc.user"  value="wafflesAreYummie" /> 
     <property name="javax.persistence.jdbc.password" value="poniesRock" /> 

     <property name="hibernate.show_sql"  value="true" /> 
     <property name="hibernate.hbm2ddl.auto" value="create" /> 
    </properties> 

</persistence-unit> 
</persistence> 

MySQL表描述:

mysql> describe foobar; 
+------------+--------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+------------+--------------+------+-----+---------+----------------+ 
| id   | int(11)  | NO | PRI | NULL | auto_increment | 
| rcpt_what | varchar(255) | YES |  | NULL |    | 
| rcpt_where | varchar(255) | YES |  | NULL |    | 
| rcpt_who | varchar(255) | YES |  | NULL |    | 
+------------+--------------+------+-----+---------+----------------+ 
4 rows in set (0.00 sec) 

回答

120

JPQL 大多是不區分大小寫的。區分大小寫的事情之一是Java實體名稱。將您的查詢更改爲:

"SELECT r FROM FooBar r" 
+3

那麼,對於類名而不是表名呢? –

+27

是的。儘管看起來像sql,但您正在執行JPA查詢語言;所以你從實體中選擇,而不是從表中選擇。 – Chris

+11

***你是我2011年12月份的英雄。***謝謝。我已經吹了一個多小時... –

14

此錯誤還有另一個可能的來源。 在一些J2EE/Web容器(在我下的Jboss 7.x和Tomcat的7.x的經驗),你必須添加的每個班級要用作休眠實體到文件的persistence.xml使用作爲

<class>com.yourCompanyName.WhateverEntityClass</class>

在jboss的情況下,這涉及到每個實體類(本地 - 即在您正在開發的項目中或在庫中)。對於Tomcat 7.x,這僅涉及庫中的實體類。

@Table(name = "foobar") 
public class FooBar { 

你需要寫的類名搜索:

3

因爲你已經宣佈你的班。
from FooBar