wake-up-neo.net

Nicht in der HQL-Abfrage zugeordneter Fehler im Ruhezustand der Tabelle

Ich habe eine Webanwendung, die Hibernate verwendet, um CRUD-Vorgänge über eine Datenbank auszuführen. Ich habe eine Fehlermeldung erhalten, dass die Tabelle nicht zugeordnet ist. Siehe die Java-Dateien:

Fehlermeldung:

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

Hier ist meine DAO.Java Methode:

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

Wie muss ich es ändern, um zu funktionieren?

47
Pascut

Was sagt die Ausnahmemeldung? Es sagt:

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

Was sagt dir das? Es sagt Ihnen, dass Books nicht zugeordnet ist. Das heißt, es gibt keinen zugeordneten Typ mit dem Namen Books.

Und in der Tat gibt es nicht. Ihr zugeordneter Typ heißt Book. Es ist einer Tabelle mit dem Namen Books zugeordnet, der Typ heißt jedoch Book. Wenn Sie HQL- (oder JPQL-) Abfragen schreiben, verwenden Sie die Namen der Typen und nicht die Tabellen.

Ändern Sie also Ihre Abfrage in:

select count(*) from Book

Obwohl ich denke, dass es sein muss

select count(b) from Book b

Wenn HQL die * -Notation nicht unterstützt.

Aus dem Lesen von Ausnahmemeldungen können Sie viel lernen!

98
Tom Anderson

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

Hibernate versucht zu sagen, dass es keine Entität mit dem Namen "Books" kennt. Schauen wir uns Ihr Unternehmen an:

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

Richtig. Der Tabelle Name für Book wurde in "Books" umbenannt, aber der Entitätsname ist immer noch "Book" aus dem Klassennamen. Wenn Sie den Entitätsnamen festlegen möchten, sollten Sie stattdessen den Namen der Annotation @Entity Verwenden:

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

Dadurch werden sowohl der Entitätsname als auch der Tabellenname festgelegt.


Das gegenteilige Problem trat auf, als ich von der Datei Person.hbm.xml Auf die Verwendung der Anmerkungen Java) zur Beschreibung der Ruhezustandsfelder migrierte. Meine alte XML-Datei hatte:

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

Und meine neue Entität hatte eine @Entity(name=...), die ich brauchte, um den Namen der Tabelle zu setzen.

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

Was ich dann sah, war HQL-Fehler wie:

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

Das Problem dabei war, dass der Entitätsname ebenfalls in persons umbenannt wurde. Ich hätte den Tabellennamen setzen sollen mit:

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

Hoffe das hilft anderen.

15
Gray

Danke an alle. Viele gute Ideen ... Dies ist meine erste Bewerbung in Spring und Hibernate.

Bitte lesen Sie die Antworten von Tom Anderson und Roman C. Sie haben das Problem sehr gut erklärt. Und ihr habt mir alle geholfen. Ich ersetzte 

SELECT COUNT(*) FROM Books

mit

select count(book.id) from Book book

Und natürlich habe ich diese Spring-Konfiguration:

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

Vielen Dank nochmal!

3
Pascut

Diese Antwort kommt spät, fasst aber das Konzept zusammen, das in der Ausnahme "Tabelle nicht zugeordnet" enthalten ist (um denjenigen zu helfen, die auf dieses Problem stoßen, da es für Hibernate-Neulinge sehr häufig ist). Dieser Fehler kann aus vielen Gründen auftreten. Ziel ist es jedoch, den häufigsten Fehler anzusprechen, mit dem einige Entwickler, die sich in den Ruhezustand versetzen, stundenlang nachforschen müssen. Ich verwende mein eigenes Beispiel für eine einfache Demonstration.

Die Ausnahme:

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

Diese sehr gewöhnliche Ausnahme besagt in einfachen Worten nur, dass die Abfrage im folgenden Code falsch ist. 

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

So wird meine POJO-Klasse deklariert:

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

Die Abfragesyntax "from subscriber" ist jedoch korrekt und die Tabelle subscriber ist vorhanden. Was mich zu einem wichtigen Punkt bringt:

  • Es ist eine HQL-Abfrage, nicht SQL.

und wie es hier erklärt

HQL arbeitet mit persistenten Objekten und deren Eigenschaften, nicht mit den Datenbanktabellen und -spalten. 

Da es sich bei der obigen Abfrage um eine HQL-Abfrage handelt, soll die subscriber ein Entitätsname und kein Tabellenname sein. Da ich meine Tabelle subscriber mit der Entität Subscriber zugeordnet habe. Mein Problem löst sich, wenn ich den Code folgendermaßen ändere:

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

Nur um Sie vor Verwirrung zu bewahren. Bitte beachten Sie, dass HQL in einigen Fällen die Groß- und Kleinschreibung berücksichtigt. Sonst hätte es in meinem Fall funktioniert.

Schlüsselwörter wie SELECT, FROM und WHERE usw. berücksichtigen nicht die Groß- und Kleinschreibung, sondern Eigenschaften wie Tabellen- und Spaltennamen sind in HQL von Groß- und Kleinschreibung abhängig.

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

Um zu verstehen, wie Hibernate-Mapping funktioniert, lesen Sie this

2
Sibgha

In der Spring-Konfiguration typo applicationContext.xml, wo die konfigurierte sessionFactory diese Eigenschaft verwendet

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
  <property name="packagesToScan" value="${package.name}"/>
1
Roman C

Hibernate ist auch wählerisch bei der Kapitalisierung. Standardmäßig ist dies der Klassenname mit dem Anfangsbuchstaben Großbuchstaben. Wenn Ihre Klasse FooBar heißt, übergeben Sie "foobar" nicht. Sie müssen "FooBar" mit genau dieser Groß-/Kleinschreibung übergeben, damit es funktioniert.

0
Jon

Neben der akzeptierten Antwort besteht eine weitere Prüfung darin, sicherzustellen, dass Sie beim Einrichten Ihrer Session Factory den richtigen Verweis auf Ihr Entity-Paket in sessionFactory.setPackagesToScan (...) haben.

0
Durja Arai