Error de tabla de hibernación no asignada


Tengo una aplicación web que utiliza Hibernate para realizar operaciones CRUD sobre una base de datos. Tengo un error diciendo que la tabla no está mapeada. Ver los archivos 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 DAO.java método:

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 que funcione?

Author: Gray, 2013-01-21

6 answers

¿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 mapeado llamado Books.

Y de hecho, no lo hay. Su tipo mapeado se llama Book. Se asigna a una tabla llamada Books, pero el tipo se llama Book. Cuando se escriben consultas HQL (o JPQL), se utilizan los nombres de los tipos, no las tablas.

Entonces, cambia tu consulta a:

select count(*) from Book

Aunque creo que puede necesitar ser

select count(b) from Book b

Si HQL no soporta la notación *.

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

 89
Author: Tom Anderson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-21 20:34:45

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

Hibernate está tratando de decir que no conoce una entidad llamada "Libros". Veamos su entidad:

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

Correcto. El nombre de la tabla para Book ha sido renombrado a "Books", pero el nombre de la entidad sigue siendo "Book" 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 {

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


Un poco diferente el problema me ocurrió 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:

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

Y mi nueva entidad tenía un @Entity(name=...) que pensé que necesitaba para 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 de 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 estaba siendo renombrado. 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 otros.

 12
Author: Gray,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-07 14:25:33

Gracias a todos. Muchas buenas ideas. Esta es mi primera aplicación en primavera e Hibernación.. 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.He sustituido

SELECT COUNT(*) FROM Books

Con

select count(book.id) from Book book

Y por supuesto, tengo esta Primavera config:

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

Gracias a todos de nuevo!

 3
Author: Pascut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-12 11:30:21

En el error de configuración de primavera applicationContext.xml donde el sessionFactory configurado poner esta propiedad

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
  <property name="packagesToScan" value="${package.name}"/>
 1
Author: Roman C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-21 20:38:17

Esta respuesta llega tarde, pero resume el concepto involucrado en la excepción "tabla no mapeada" (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 objetivo es abordar la más común a la que se enfrentan varios desarrolladores de hibernación novatos 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 simple palabras, esta excepción muy habitual solo dice que la consulta es incorrecta en el código de abajo.

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

Así es como se declara mi clase POJO:

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

Pero la sintaxis de consulta "from subscriber" es correcta y la tabla subscriber 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 de la base de datos y columna.

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

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

Solo para evitar que te confundas. Tenga en cuenta que HQL distingue entre mayúsculas y minúsculas en varios casos. De lo contrario habría funcionado en mi caso.

Palabras clave como SELECT, FROM y WHERE, etc. no distinguen entre mayúsculas y minúsculas, pero propiedad al igual que los nombres de tabla y columna son sensibles a 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

 1
Author: Sibgha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-04 16:45:49

Hibernar también es exigente con la capitalización. Por defecto va a ser el nombre de la clase con la Primera letra en mayúscula. Así que si tu clase se llama FooBar, no pases "foobar". Tienes que pasar "FooBar" con esa mayúscula exacta para que funcione.

 0
Author: Jon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-16 14:20:44