HQL查询中的休眠表未映射错误
Posted
技术标签:
【中文标题】HQL查询中的休眠表未映射错误【英文标题】:Hibernate table not mapped error in HQL query 【发布时间】: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;
...
我应该如何修改它才能工作?
【问题讨论】:
什么是持久化类的包名? 请重新表述,我不明白你的想法 请填写班级名称。问题可能与表名的定义有关。请检查两个地方是否使用相同的名称。 (区分大小写) 【参考方案1】:在 Spring 配置错误 applicationContext.xml
中配置的 sessionFactory
放置了这个属性
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="packagesToScan" value="$package.name"/>
【讨论】:
我不知道包名是什么,所以我把上下文属性作为它的名字 现在是:异常消息说:
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
没错。 Book
的 table 名称已重命名为“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
存在。这让我想到了一个关键点:
以及它的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();
);
【讨论】:
以上是关于HQL查询中的休眠表未映射错误的主要内容,如果未能解决你的问题,请参考以下文章
JPQL 构造函数表达式 - org.hibernate.hql.ast.QuerySyntaxException:表未映射