org.hibernate.hql.internal.ast.QuerySyntaxException: table is not mapped Hibernate查询语法异常:表未映射

127

我有一个例子Web应用程序,使用Hibernate 4.3.5 + Derby数据库10.10.1.1 + Glassfish4.0和IDE NetBeans 8.0Beta。

我遇到了以下异常:

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: CUSTOMERV is not mapped
at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:189)
at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:109)
at org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:95)
at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:331)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3633)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3522)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:706)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:562)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:299)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:247)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
... 72 more 

来自index.xhtml的表单

<h:panelGrid id="panel1" columns="2" border="1"
                 cellpadding="5" cellspacing="1">
        <f:facet name="header">
            <h:outputText value="Add Customer Information"/>
        </f:facet>
        <h:outputLabel value="First Name:"/>
        <h:inputText value="#{customer.firstName}" id="fn"/>
        <h:outputLabel value="Last Name:"/>
        <h:inputText value="#{customer.lastName}" id="ln"/>
        <h:outputLabel value="Email:"/>
        <h:inputText value="#{customer.email}" id="eml"/>
        <h:outputLabel value="Date of Birth:"/>
        <h:inputText value="#{customer.sd}" id="s"/>
        <f:facet name="footer">
            <h:outputLabel value="#{customer.msg}" id="msg" styleClass="msg"/>
            <h:commandButton value="Save" action="#{customer.saveCustomer}">
            </h:commandButton>
        </f:facet>
    </h:panelGrid> 

Customer.java

    package com.javaknowledge.entity;

    import com.javaknowledge.dao.CustomerDao;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.SessionScoped;
    import javax.persistence.*;    

    @ManagedBean
    @SessionScoped

    public class Customer implements java.io.Serializable {

    private Integer custId;
    private String firstName;
    private String lastName;
    private String email;
    private Date dob;
    private String sd, msg, selectedname;
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");


    public Customer() {
    }

    public Customer(String firstName, String lastName, String email, Date dob) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.dob = dob;
    }

    public String getSd() {
        return sd;
    }

    public void setSd(String sd) {
        this.sd = sd;
    }

    public Integer getCustId() {
        return this.custId;
    }

    public void setCustId(Integer custId) {
        this.custId = custId;
    }

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return this.lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    @Column(name = "EMAIL")
    public String getEmail() {
        return this.email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Column(name = "DOB")
    public Date getDob() {
        return this.dob;
    }

    public void setDob(Date dob) {
        this.dob = dob;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getSelectedname() {
        return selectedname;
    }

    public void setSelectedname(String selectedname) {
        this.selectedname = selectedname;
    }

    public void saveCustomer() {
        try {
            Date d = sdf.parse(sd);
            System.out.println(d);
            this.dob = d;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        CustomerDao dao = new CustomerDao();
        dao.addCustomer(this);
        this.msg = "Member Info Saved Successfull!";
        clearAll();
    }
    public void updateCustomer() {
        try {
            Date d = sdf.parse(sd);
            System.out.println(d);
            this.dob = d;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        CustomerDao dao = new CustomerDao();
        dao.updateCustomer(this);
        this.msg = "Member Info Update Successfull!";
        clearAll();
    }
    public void deleteCustomer() {
        CustomerDao dao = new CustomerDao();
        dao.deleteCustomer(custId);
        this.msg = "Member Info Delete Successfull!";
        clearAll();
    }

    public List<Customer> getAllCustomers() {
        List<Customer> users = new ArrayList<Customer>();
        CustomerDao dao = new CustomerDao();
        users = dao.getAllCustomers();
        return users;
    }

    public void fullInfo() {
        CustomerDao dao = new CustomerDao();
        List<Customer> lc = dao.getCustomerById(selectedname);
        System.out.println(lc.get(0).firstName);
        this.custId = lc.get(0).custId;
        this.firstName = lc.get(0).firstName;
        this.lastName = lc.get(0).lastName;
        this.email = lc.get(0).email;
        this.dob = lc.get(0).dob;
        this.sd = sdf.format(dob);
    }

    private void clearAll() {
        this.firstName = "";
        this.lastName = "";
        this.sd = "";
        this.email = "";
        this.custId=0;
    }

   }

hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.DerbyDialect</property>
    <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
    <property name="hibernate.connection.url">jdbc:derby://localhost:1527/derbyDB</property>
    <property name="hibernate.connection.username">user1</property>
    <property name="hibernate.connection.password">user1</property>
    <property name="hibernate.hbm2ddl.auto">create</property>

    <property name="c3p0.min_size">1</property>
    <property name="c3p0.max_size">5</property>
    <property name="c3p0.timeout">300</property>
    <property name="c3p0.max_statements">50</property>
    <property name="c3p0.idle_test_period">300</property>

    <mapping class="com.javaknowledge.entity.Customer" resource="com/javaknowledge/entity/Customer.hbm.xml"/>
  </session-factory>
</hibernate-configuration>

Customer.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="com.javaknowledge.entity.Customer" table="CUSTOMERV" schema="APP">
        <id name="custId" type="java.lang.Integer">
            <column name="cust_id" />
            <generator class="increment" />
        </id>
        <property name="firstName" type="string">
            <column name="first_name" length="45" not-null="true" />
        </property>
        <property name="lastName" type="string">
            <column name="last_name" length="45" not-null="true" />
        </property>
        <property name="email" type="string">
            <column name="email" length="45" not-null="true" />
        </property>
        <property name="dob" type="date">
            <column name="dob" length="10" not-null="true" />
        </property>
   </class>
</hibernate-mapping>

无论您使用NativeSQL还是使用JPQL,如果使用JPQL,请确保将变量名和表名用作类名。 - Smart Coder
3
如果使用JPQL,则使用类名而不是表名,否则可能会出现此错误。 - Smart Coder
22个回答

156

最后我发现了一个错误!希望对某人有用。当向数据库发送请求(在我的情况下是Apache Derby)时,数据库名需要将第一个字母大写,其余小写。

以下查询是错误的:

session.createQuery("select first_name from CUSTOMERV").

这是有效的查询

session.createQuery("select first_name from Customerv"). 

类实体的名称必须与数据库相同,但我不确定。


51
可能不是这个原因。选择从客户端c查询是正确的,因为Customer是您的类名,我们应该在查询中写类名而不是表名。另外,在您的hibernate.cfg.xml中,您已经给出了<mapping resource>和<class>两者,只需要一个即可。请检查一下。 - Shoaib Chikate
7
太好了,对我有效的唯一方法就是使用格式良好的类名而不是数据库表名本身。我认为Hibernate需要这样做才能进行正确的映射。虽然这有点令人困惑,不像JDBC那样通常的方式,但我希望未来的版本能够解决这个问题。保留一些JDBC的风格对于某些查询机制来说会是一个加分项。 - Akah
4
谢谢。这对我有用。实际上,它需要实体/类名而不是表名。例如:如果您的表名是CUSTOMER,实体名称为Customer,则在查询中将使用Customer作为HQL查询。 - Terry

88

HQL查询中,不要编写表名称,请在查询中编写您的实体类名称,例如

String s = "from Entity_class name";
query qry = session.createUqery(s);

44

在我的情况下,我只是忘记添加 nativeQuery = true

@Query( value = "some sql query ...", nativeQuery = true)

对于使用Spring Data JPA的Spring Boot


23
如果你正在使用JPA注解来创建实体,那么请确保将表名与@Table注解一起映射,而不是@Entity。
错误的映射:


不正确的映射:

@Entity(name="DB_TABLE_NAME")
public class DbTableName implements Serializable {
   ....
   ....
}

正确映射的实体:

@Entity
@Table(name="DB_TABLE_NAME")
public class DbTableName implements Serializable {
   ....
   ....
}

16

hibernate.cfg.xml文件应该像下面这样具有表的映射。检查您的文件是否缺少此内容。

......
<hibernate-configuration>
......
......
  <session-factory>
......
<mapping class="com.test.bean.dbBean.testTableHibernate"/>
......
 </session-factory>

</hibernate-configuration>
.....

1
这对我来说是个问题,当我将实现更改为与Oracle DB一起使用时,而不是Derby - 使用Derby时,由于某种原因,在persistence.xml中声明实体是不必要的(对我来说似乎很合理,因为实体已经被注释了)(也许是因为旧驱动程序(ojdbc6))。 - hello_earth

8

对我来说,其他解决方案都没有起作用。

即使我不认为这是最佳实践,我不得不像这样将其添加到代码中

configuration.addAnnotatedClass(com.myOrg.entities.Person.class);

这里

public static SessionFactory getSessionFactory() {
    Configuration configuration = new Configuration().configure();

    configuration.addAnnotatedClass(com.myOrg.entities.Person.class);

    StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
            .applySettings(configuration.getProperties());
    SessionFactory sessionFactory = configuration.buildSessionFactory(builder.build());
    return sessionFactory;
}

6

在 Hibernate 中,

session.createQuery("select first_name from Customerv"). 
< p > Customerv 是你的实体名称,而不是你的表格名称


5

即使我们使用类名,如果我们在不同的包中有两个同名的类,仍然有一次获得此异常的机会。我认为hibernate可能会出现歧义并抛出此异常,因此解决方案是使用完全限定名称(例如com.test.Customerv)。

我添加了这个答案,将有助于我提到的场景。我曾经遇到过相同的情况,并卡住了一段时间。


5

当我开始使用Hibernate时,我也遇到了类似的问题。总的来说,我可以说,在createQuery中需要传递实体类的名称而不是实体映射到的表名。


5
这意味着您的表未映射到JPA。 可能是表名错误(大小写敏感),或者您需要在XML文件中添加一个条目。
祝编码愉快 :)

在哪个 XML 文件中? - Subrahmanyam Janapamula
@SubrahmanyamJanapamula - 如果您正在使用Spring Boot和JPA,则无需任何XML文件映射。 - Karan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接