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?
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!
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.
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!
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:
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
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}"/>
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.
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.