2011-11-22 218 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