Error de tabla de Hibernate no mapeada

Tengo una aplicación web que utiliza Hibernate para realizar operaciones CRUD en una base de datos. Recibí un error al decir que la tabla no está asignada. Vea los archivos de Java:

Mensaje de error:

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

Aquí está mi método 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; ... } 

¿Cómo debo modificarlo para poder trabajar?

¿Qué dice el mensaje de excepción? Dice:

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

¿Qué te dice eso? Te dice que Books no está mapeado. Es decir, que no hay un tipo de mapa llamado Books .

Y de hecho, no hay. Su tipo mapeado se llama Book . Está asignado a una tabla llamada Books , pero el tipo se llama Book . Cuando escribe consultas HQL (o JPQL), usa los nombres de los tipos, no las tablas.

Por lo tanto, cambie su consulta a:

select count(*) from Book

Aunque creo que puede necesitar ser

select count(b) from Book b

Si HQL no admite la notación * .

¡Hay mucho que puedes aprender de leer mensajes de excepción!

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

Hibernate intenta decir que no conoce una entidad llamada “Libros”. Veamos tu entidad:

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

Derecha. El nombre de la tabla para el Book ha cambiado de nombre a “Libros”, pero el nombre de la entidad sigue siendo “Libro” del nombre de la clase. Si desea establecer el nombre de la entidad, debe usar el nombre en la anotación @Entity :

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

Eso establece tanto el nombre de la entidad como el nombre de la tabla.


Un problema ligeramente diferente me sucedió cuando estaba migrando desde el archivo Person.hbm.xml a usar las anotaciones Java para describir los campos de hibernación. Mi antiguo archivo XML tenía:

   ...  

Y mi nueva entidad tenía un @Entity(name=...) que pensé que necesitaba establecer el nombre de la tabla.

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

Lo que entonces estaba viendo eran errores HQL como:

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

El problema con esto era que el nombre de la entidad también se cambiaba de nombre. Debería haber puesto el nombre de la tabla usando:

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

Espero que esto ayude a otros.

Gracias a todos. Muchas buenas ideas. Esta es mi primera aplicación en Spring e Hibernate … así que un poco más de paciencia cuando se trata de “novatos” como yo …

Por favor, lea las respuestas de Tom Anderson y Roman C. Explicaron muy bien el problema. Y todos ustedes me ayudaron. Reemplacé

 SELECT COUNT(*) FROM Books 

con

 select count(book.id) from Book book 

Y, por supuesto, tengo esta configuración Spring:

   

¡Gracias a todos de nuevo!

En la configuración de Spring typo applicationContext.xml donde se configuró sessionFactory puso esta propiedad

   

Esta respuesta llega tarde, pero resume el concepto involucrado en la excepción “tabla no asignada” (para ayudar a aquellos que se encuentran con este problema, ya que es muy común para los novatos en hibernación). Este error puede aparecer debido a muchas razones, pero el objective es abordar el más común al que se enfrentan varios desarrolladores de hibernación noveles para ahorrarles horas de investigación. Estoy usando mi propio ejemplo para una demostración simple a continuación.

La excepción:

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

En palabras simples, esta excepción muy habitual solo dice que la consulta es incorrecta en el código siguiente.

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

Así es como se declara mi clase POJO:

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

Pero la syntax de la consulta “del suscriptor” es correcta y el subscriber la tabla existe. Lo que me lleva a un punto clave:

  • Es una consulta HQL no SQL.

y cómo se explica aquí

HQL funciona con objetos persistentes y sus propiedades, no con las tablas y columnas de la base de datos.

Dado que la consulta anterior es una HQL uno, se supone que el subscriber es un nombre de entidad y no un nombre de tabla. Como tengo mi subscriber tabla mapeado con la entidad Subscriber . Mi problema se resuelve si cambio el código a este:

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

Solo para evitar que te confundas. Tenga en cuenta que HQL es sensible a mayúsculas y minúsculas en varios casos. De lo contrario, hubiera funcionado en mi caso.

Las palabras clave como SELECT, FROM y WHERE, etc. no distinguen entre mayúsculas y minúsculas, pero las propiedades como los nombres de tabla y columna distinguen entre mayúsculas y minúsculas en HQL.

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

Para comprender mejor cómo funciona el mapeo de hibernación, lea esto

Hibernate también es exigente con la capitalización. Por defecto, será el nombre de la clase con la Primera letra en mayúscula. Entonces, si su clase se llama FooBar , no pase "foobar" . Tienes que pasar "FooBar" con esa capitalización exacta para que funcione.