Hibernate table not mapped error in HQL query

The exception message says:

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 is not mapped. That is, that there is no mapped type called Books.

And indeed, there isn't. Your mapped type is called Book. It's mapped to a table called Books, but the type is called Book. When you write HQL (or JPQL) queries, you use the names of the types, not the tables.

So, change your query to:

select count(*) from Book

Although I think it may need to be

select count(b) from Book b

If HQL doesn't support the * notation.


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

Hibernate is trying to say that it does not know an entity named "Books". Let's look at your entity:

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

Right. The table name for Book has been renamed to "Books" but the entity name is still "Book" from the class name. If you want to set the entity name, you should use the @Entity annotation's name instead:

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

That sets both the entity name and the table name.


The opposite problem happened to me when I was migrating from the Person.hbm.xml file to using the Java annotations to describe the hibernate fields. My old XML file had:

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

And my new entity had a @Entity(name=...) which I needed to set the name of the table.

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

What I then was seeing was HQL errors like:

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

The problem with this was that the entity name was being renamed to persons as well. I should have set the table name using:

// 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 {

This answer comes late but summarizes the concept involved in the "table not mapped" exception(in order to help those who come across this problem since its very common for hibernate newbies). This error can appear due to many reasons but the target is to address the most common one that is faced by a number of novice hibernate developers to save them hours of research. I am using my own example for a simple demonstration below.

The exception:

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

In simple words, this very usual exception only tells that the query is wrong in the below code.

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

This is how my POJO class is declared:

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

But the query syntax "from subscriber" is correct and the table subscriber exists. Which brings me to a key point:

  • It is an HQL query not SQL.

and how its explained here

HQL works with persistent objects and their properties not with the database tables and columns.

Since the above query is an HQL one, the subscriber is supposed to be an entity name not a table name. Since I have my table subscriber mapped with the entity Subscriber. My problem solves if I change the code to this:

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

Just to keep you from getting confused. Please note that HQL is case sensitive in a number of cases. Otherwise it would have worked in my case.

Keywords like SELECT , FROM and WHERE etc. are not case sensitive but properties like table and column names are case sensitive in HQL.

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

To further understand how hibernate mapping works, please read this


Thanks everybody. Lots of good ideas. This is my first application in Spring and Hibernate.. so a little more patience when dealing with "novices" like me..

Please read Tom Anderson and Roman C.'s answers. They explained very well the problem. And all of you helped me.I replaced

SELECT COUNT(*) FROM Books

with

select count(book.id) from Book book

And of course, I have this Spring config:

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

Thank you all again!