Hibernate table not mapped error in HQL query

218,145

Solution 1

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.

Solution 2

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 {

Solution 3

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

Solution 4

Ensure your have the Entity annotation and Table annotation and set the table name on the table annotation.

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

}

Solution 5

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!

Share:
218,145

Related videos on Youtube

Pascut
Author by

Pascut

Updated on July 05, 2022

Comments

  • Pascut
    Pascut almost 2 years

    I have a web application that use Hibernate to make CRUD operations over a database. I got an error saying that the table is not mapped. See the Java files:

    Error message:

    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)
    ...
    

    Here's my DAO.java method:

    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;
        ...
    }
    

    How should I modify it in order to work?

    • Roman C
      Roman C over 11 years
      What a package name where persistence classes?
    • Pascut
      Pascut over 11 years
      please reformulate, I don't understand your idea
    • FullStackDev
      FullStackDev almost 7 years
      Please name of the class. Issue might be with definition of table name. Please check if the same name is used in both the places. (Case sensitive)
  • Roman C
    Roman C over 11 years
    I don't know what is the package name so I've put context property for its name
  • Pascut
    Pascut over 11 years
    this is not working, see the error: Caused by: org.hibernate.hql.ast.QuerySyntaxException: Books is not mapped [select count(*) from Books]
  • Pascut
    Pascut over 11 years
    right now it is: <property name="dataSource"><ref local="dataSource"/></property> <property name="packagesToScan" value="extjs.model" /> But it's not working..
  • Roman C
    Roman C over 11 years
    extjs.model.Books should be there, not in the property but in the package
  • Pascut
    Pascut over 11 years
    not working: Caused by: org.hibernate.hql.ast.QuerySyntaxException: Books is not mapped [select count(*) from Books] and now it is: <property name="dataSource"><ref local="dataSource"/></property> <property name="packagesToScan" value="extjs.model.Book" />
  • Roman C
    Roman C over 11 years
    Because your class named Book instead of Books
  • Pascut
    Pascut over 11 years
    now I understand what you're saying, I'm in a rush so I just read quickly all the answers..my bad. I'll try now to change from Books to Book. I think you're right
  • Roman C
    Roman C over 11 years
    in the property should be the name of the package not the name of the class
  • Roman C
    Roman C over 11 years
    you should either change the class name to plural or change the query to singular name
  • Pascut
    Pascut over 11 years
    initially it was: <property name="dataSource"><ref local="dataSource"/></property> <property name="packagesToScan" value="extjs.model" /> I changed it because you said so..
  • Roman C
    Roman C over 11 years
    I said to change it to the package name not the class name as you did
  • Pascut
    Pascut over 11 years
    you were right with your first answer.. the package should be there. But the problem was that I was using Books instead of Book. Thanks anyway..
  • Roman C
    Roman C over 11 years
    along as I read the comments from answers you wanted to create hibernare.cfg.xml for this should be another property <property name="configLocation" value="classpath:hibernate.cfg.xml"/>
  • Roman C
    Roman C over 11 years
    these properties are mutual exclusive
  • Roman C
    Roman C over 11 years
    in the hibernate.cfg.xml should be <mapping package="extjs.model" />, this still useful to IDE.
  • Pascut
    Pascut over 11 years
    these settings are very important, your answers will help lots of peoples :D
  • Michael Plautz
    Michael Plautz over 9 years
    The key takeaway here for me is: In your HQL, you must use Entity names and not table names. That made all the difference.
  • Philip Rego
    Philip Rego about 6 years
    Sure it says it's not mapped but the error and you don't say how to do the mapping.
  • Gray
    Gray over 5 years
    How does this add to the answers that you reference? Duplicating their information doesn't really help the page as a reference.
  • Pascut
    Pascut over 5 years
    I don't understand what's your point here, I haven't created this answer to get more upvotes. I created a synthesis of all the answers. This is not the accepted answer as you can well see. My answer is from 2013, your answer is from 2016. So you say that my answer is extra? Sorry but you are looking for upvotes.
  • Gray
    Gray over 5 years
    Nope, not looking for upvotes @pascut. Just looking to make sure there isn't duplicate information. Just about every question has multiple answers but I tend to ask folks to think about removal if their's doesn't add anything new and comes later.
  • Pascut
    Pascut over 5 years
    Thanks for your good intentions. I do believe that my answer also adds good value to the question.
  • Java Main
    Java Main about 4 years
    Dont mix between the table name and the repository name. Your hibernate query is against the repository
  • phil
    phil almost 4 years
    Be aware: This error appears also if you use SELECT b FROM book because it is case-sensitive. Instead you should the exact classname (SELECT b FROM Book)
  • izogfif
    izogfif over 3 years
    Exactly my case: I had @Entity(name = "table_name") but didn't have @Table annotation. After I changed it to @Entity @Table(name = "table_name"), it worked. Note: didn't have to specify (name = "table_name") for @Entity annotation.