79

我有一个使用 Hibernate 对数据库进行 CRUD 操作的 Web 应用程序。我收到一个错误,说该表未映射。查看 Java 文件:

错误信息:

org.springframework.orm.hibernate3.HibernateQueryException: Books is not mapped [SELECT COUNT(*) FROM Books]; nested exception is org.hibernate.hql.ast.QuerySyntaxException: Books is not mapped [SELECT COUNT(*) FROM Books]
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:660)
at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411)
...
Caused by: org.hibernate.hql.ast.QuerySyntaxException: Books is not mapped [SELECT COUNT(*) FROM Books]
at org.hibernate.hql.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:181)
at org.hibernate.hql.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:111)
at org.hibernate.hql.ast.tree.FromClause.addFromElement(FromClause.java:93)
...

这是我的DAO.java方法:

public int getTotalBooks(){
    return DataAccessUtils.intResult(hibernateTemplate.find(
          "SELECT COUNT(*) FROM Books"));
}

Book.java

@Entity
@Table(name="Books")
public class Book {

    @Id
    @GeneratedValue
    @Column(name="id")
    private int id;

    @Column(name="title", nullable=false)
    private String title;
    ...
}

我应该如何修改它才能工作?

4

9 回答 9

147

异常消息说:

Books is not mapped [SELECT COUNT(*) FROM Books]; nested exception is org.hibernate.hql.ast.QuerySyntaxException: Books is not mapped [SELECT COUNT(*) FROM Books]

Books未映射。也就是说,没有称为的映射类型Books

事实上,没有。您的映射类型称为Book. 它映射到名为 的表Books,但类型名为Book。当您编写 HQL(或 JPQL)查询时,您使用类型的名称,而不是表。

因此,将您的查询更改为:

select count(*) from Book

虽然我认为它可能需要

select count(b) from Book b

如果 HQL 不支持该*表示法。

于 2013-01-21T20:34:45.777 回答
23

hibernate3.HibernateQueryException: Books is not mapped [SELECT COUNT(*) FROM Books];

Hibernate 试图说它不知道名为“Books”的实体。让我们看看你的实体:

@javax.persistence.Entity
@javax.persistence.Table(name = "Books")
public class Book {

正确的。表名已重命名为“Books”,但实体名称仍是类名中的“Book” Book如果要设置实体名称,则应使用@Entity注解的名称:

// this allows you to use the entity Books in HQL queries
@javax.persistence.Entity(name = "Books")
public class Book {

这将设置实体名称和表名称。


当我从Person.hbm.xml文件迁移到使用 Java 注释来描述休眠字段时,发生了相反的问题。我的旧 XML 文件有:

<hibernate-mapping package="...">
    <class name="Person" table="persons" lazy="true">
       ...
</hibernate-mapping>

我的新实体有一个@Entity(name=...)我需要设置表的名称。

// this renames the entity and sets the table name
@javax.persistence.Entity(name = "persons")
public class Person {
    ...

然后我看到的是 HQL 错误,例如:

QuerySyntaxException: Person is not mapped
     [SELECT id FROM Person WHERE id in (:ids)]

这样做的问题是实体名称也被重命名persons为。我应该使用以下方法设置表名:

// no name = here so the entity can be used as Person
@javax.persistence.Entity
// table name specified here
@javax.persistence.Table(name = "persons")
public class Person extends BaseGeneratedId {
于 2016-07-20T15:28:39.103 回答
14

这个答案来晚了,但总结了“表未映射”异常中涉及的概念(为了帮助那些遇到这个问题的人,因为它对于休眠新手来说很常见)。由于许多原因,可能会出现此错误,但目标是解决一些 Hibernate 新手开发人员面临的最常见错误,以节省他们数小时的研究时间。我在下面使用我自己的示例进行简单演示。

例外:

org.hibernate.hql.internal.ast.QuerySyntaxException: subscriber is not mapped [ from subscriber]

简而言之,这个非常常见的异常仅表明以下代码中的查询是错误的。

Session session = this.sessionFactory.getCurrentSession();
List<Subscriber> personsList = session.createQuery(" from subscriber").list();

这就是我的 POJO 类的声明方式:

@Entity
@Table(name = "subscriber")
public class Subscriber

但是“来自订阅者”的查询语法是正确的,并且该表subscriber存在。这让我想到了一个关键点:

  • 这是一个 HQL 查询而不是 SQL。

以及它是如何在这里解释的

HQL 适用于持久对象及其属性,而不适用于数据库表和列。

由于上述查询是 HQL 查询,因此subscriber应该是实体名称而不是表名称。因为我的表subscriber 与实体映射Subscriber。如果我将代码更改为此,我的问题就解决了:

Session session = this.sessionFactory.getCurrentSession();
List<Subscriber> personsList = session.createQuery(" from Subscriber").list();

只是为了让你不迷茫。请注意,HQL 在许多情况下都区分大小写。否则它会在我的情况下工作。

SELECT、FROM 和 WHERE 等关键字不区分大小写,但 HQL 中的表名和列名等属性区分大小写。

https://www.tutorialspoint.com/hibernate/hibernate_query_language.htm

要进一步了解休眠映射的工作原理,请阅读此内容

于 2017-04-04T16:45:49.487 回答
3

谢谢大家。很多好主意。这是我在 Spring 和 Hibernate 中的第一个应用程序.. 所以在与像我这样的“新手”打交道时要多一点耐心..

请阅读 Tom Anderson 和 Roman C. 的回答。他们很好地解释了这个问题。你们都帮了我。我换了

SELECT COUNT(*) FROM Books

select count(book.id) from Book book

当然,我有这个 Spring 配置:

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="packagesToScan" value="extjs.model"/>

再次感谢大家!

于 2013-01-21T21:04:57.180 回答
3

确保您有实体注释和表格注释,并在表格注释上设置表格名称。

@Entity
@Table(name = "table_name")
public class TableName {

}
于 2020-04-13T09:12:58.887 回答
2

除了接受的答案之外,另一项检查是确保在设置会话工厂时正确引用 sessionFactory.setPackagesToScan(...) 中的实体包。

于 2019-05-12T00:09:59.087 回答
1

在配置放置此属性的 Spring 配置错字applicationContext.xmlsessionFactory

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
  <property name="packagesToScan" value="${package.name}"/>
于 2013-01-21T20:29:58.787 回答
0

Hibernate 对大小写也很挑剔。默认情况下,它将是第一个字母大写的类名。因此,如果您的班级被调用FooBar,请不要通过"foobar"。您必须通过"FooBar"该确切的大写字母才能使其正常工作。

于 2018-04-16T14:20:44.307 回答
0

我有同样的问题,而不是@Entity 我使用以下代码来获取记录

    List<Map<String, Object>> list = null;
            list = incidentHibernateTemplate.execute(new HibernateCallback<List<Map<String, Object>>>() {

            @Override
            public List<Map<String, Object>> doInHibernate(Session session) throws HibernateException {
                Query query = session.createSQLQuery("SELECT * from table where appcode = :app");
                    query.setParameter("app", apptype);
                query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
                return query.list();

                }
            });

我使用以下代码进行更新

private @Autowired HibernateTemplate incidentHibernateTemplate;
Integer updateCount = 0;

    updateCount = incidentHibernateTemplate.execute((Session session) -> {
        Query<?> query = session
                    .createSQLQuery("UPDATE  tablename SET key = :apiurl, data_mode = :mode WHERE apiname= :api ");
          query.setParameter("apiurl", url);
          query.setParameter("api", api);
          query.setParameter("mode", mode);
            return query.executeUpdate();
        }
    );
于 2020-10-19T09:40:53.767 回答