web-dev-qa-db-ja.com

HQLクエリでHibernateテーブルがマップされていないエラー

Hibernateを使用してデータベース上でCRUD操作を行うWebアプリケーションがあります。テーブルがマップされていないというエラーが表示されました。 Javaファイルを参照してください。

エラーメッセージ:

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

これが私の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;
    ...
}

動作させるにはどのように変更する必要がありますか?

50
Pascut

例外メッセージは何を言っていますか?それは言います:

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がマッピングされていないことがわかります。つまり、Booksというマップされたタイプはありません。

そして実際、ありません。マッピングされたタイプはBookと呼ばれます。 Booksというテーブルにマップされますが、タイプはBookと呼ばれます。 HQL(またはJPQL)クエリを記述するときは、テーブルではなく、タイプの名前を使用します。

したがって、クエリを次のように変更します。

select count(*) from Book

私はそれがする必要があるかもしれないと思うけれども

select count(b) from Book b

HQLが*表記をサポートしていない場合。

例外メッセージを読むことから多くのことを学ぶことができます!

98
Tom Anderson

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

Hibernateは、 "Books"という名前のエンティティを知らないと言っています。エンティティを見てみましょう:

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

右。 tableBookの名前は「Books」に名前が変更されましたが、エンティティ名はクラス名から「Book」のままです。エンティティ名を設定する場合は、代わりに@Entityアノテーションの名前を使用する必要があります。

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

これにより、エンティティ名とテーブル名の両方が設定されます。


Person.hbm.xmlファイルからJava注釈を使用して休止状態フィールドを記述するように移行しているときに、逆の問題が発生しました。私の古いXMLファイルには次のものがありました。

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

そして、私の新しいエンティティには、テーブルの名前を設定するために必要な@Entity(name=...)がありました。

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

そのとき私が見ていたのは、次のようなHQLエラーです。

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

これに関する問題は、エンティティ名もpersonsに名前が変更されていたことでした。次を使用してテーブル名を設定する必要があります。

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

これが他の人に役立つことを願っています。

15
Gray

この答えは遅くなりますが、「table not mapped」例外に関係する概念を要約します(この問題に出くわす人は、冬眠初心者には非常に一般的であるため)。このエラーはさまざまな理由で発生する可能性がありますが、ターゲットは、多くの初心者の休止状態の開発者が直面する最も一般的なものに対処して、調査時間を節約することです。以下の簡単なデモンストレーションに自分の例を使用しています。

例外:

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

簡単な言葉で言えば、この非常に一般的な例外は、以下のコードでクエリが間違っていることを伝えるだけです。

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

これが私のPOJOクラスの宣言方法です:

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

ただし、クエリ構文 "from subscriber"は正しく、テーブルsubscriberは存在します。キーポイントに私をもたらします:

  • これは、SQLではなくHQLクエリです。

そしてその方法 ここで説明

HQLは、データベースのテーブルや列ではなく、永続オブジェクトとそのプロパティで機能します。

上記のクエリはHQLクエリであるため、subscriberはテーブル名ではなくエンティティ名であると想定されています。テーブルsubscriberがエンティティSubscriberにマップされているため。コードを次のように変更すると、私の問題は解決します。

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

混乱しないようにするためです。 HQLは多くのケースで大文字と小文字を区別することに注意してください。そうでなければ、私の場合はうまくいったでしょう。

SELECT、FROM、WHEREなどのキーワードは大文字と小文字を区別しませんが、HQLではテーブル名と列名などのプロパティは大文字と小文字を区別します。

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

ハイバネートマッピングの仕組みをさらに理解するには、 this をお読みください

3
Sibgha

みんなありがとう。たくさんの良いアイデア。これは、SpringとHibernateでの私の最初のアプリケーションです。

Tom AndersonとRoman C.の回答を読んでください。彼らは問題を非常にうまく説明しました。そして、あなたのすべてが私を助けてくれました。

SELECT COUNT(*) FROM Books

select count(book.id) from Book book

そしてもちろん、私はこのSpring設定を持っています:

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

どうもありがとうございました!

2
Pascut

Spring構成のタイプミスapplicationContext.xmlでは、sessionFactoryが構成されており、このプロパティを配置します

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

Hibernateは大文字化についてもうるさいです。デフォルトでは、最初の文字が大文字のクラス名になります。したがって、クラスがFooBarと呼ばれる場合、"foobar"を渡さないでください。 "FooBar"を渡すには、大文字と小文字を正確に一致させる必要があります。

0
Jon

受け入れられた答えに加えて、セッションファクトリのセットアップ中に、sessionFactory.setPackagesToScan(...)でエンティティパッケージへの正しい参照があることを確認することももう1つのチェックです。

0
Durja Arai