【问题标题】:Hibernate table not mapped error in HQL queryHQL查询中的休眠表未映射错误
【发布时间】:2013-01-04 22:40:53
【问题描述】:

我有一个使用 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;
    ...
}

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

【问题讨论】:

  • 什么是持久化类的包名?
  • 请重新表述,我不明白你的想法
  • 请填写班级名称。问题可能与表名的定义有关。请检查两个地方是否使用相同的名称。 (区分大小写)

标签: java eclipse spring hibernate hibernate-mapping


【解决方案1】:

在 Spring 配置错误 applicationContext.xml 中配置的 sessionFactory 放置了这个属性

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
  <property name="packagesToScan" value="${package.name}"/>

【讨论】:

  • 我不知道包名是什么,所以我把上下文属性作为它的名字
  • 现在是:但它不起作用..
  • extjs.model.Books 应该在那里,而不是在属性中,而是在包中
  • 不工作:原因:org.hibernate.hql.ast.QuerySyntaxException:书籍未映射[从书籍中选择计数(*)],现在是:
  • 因为你的班级名为 Book 而不是 Books
【解决方案2】:

异常消息说:

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 不支持 * 表示法。

【讨论】:

  • 这不起作用,请参阅错误:Caused by: org.hibernate.hql.ast.QuerySyntaxException: Books is not mapped [select count(*) from Books]
  • 现在我明白你在说什么了,我很着急,所以我只是快速阅读所有答案......我的错。我现在将尝试从 Books 更改为 Book。我认为你是对的
  • 对我来说,这里的关键点是:在您的 HQL 中,您必须使用实体名称而不是表名称。这一切都不同了。
  • 当然它说它没有映射但是错误并且你没有说如何进行映射。
  • 不要混用表名和存储库名。您的休眠查询针对存储库
【解决方案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 年的,你的答案是 2016 年的。所以你说我的答案是多余的?抱歉,您正在寻找赞成票。
  • 不,不是在寻找赞成票@pascut。只是想确保没有重复的信息。几乎每个问题都有多个答案,但我倾向于要求人们考虑删除,如果他们没有添加任何新内容并且稍后出现。
  • 感谢您的好意。我相信我的回答也为这个问题增加了很好的价值。
【解决方案4】:

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

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

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

没错。 Booktable 名称已重命名为“Books”,但实体名称仍是类名称中的“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 {

【讨论】:

    【解决方案5】:

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

    例外:

    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
    

    但是查询语法"fromsubscriber" 是正确的并且表subscriber 存在。这让我想到了一个关键点:

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

    以及它的explained here

    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

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

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        【解决方案7】:

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

        【讨论】:

          【解决方案8】:

          确保你有实体注解和表注解,并在表注解上设置表名。

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

          【讨论】:

          • 正是我的情况:我有 @Entity(name = "table_name") 但没有 @Table 注释。在我将其更改为@Entity @Table(name = "table_name") 后,它起作用了。注意:不必为@Entity 注释指定(name = "table_name")
          【解决方案9】:

          我有同样的问题,而不是@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();
                  }
              );
          

          【讨论】:

            猜你喜欢
            • 2021-09-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多