6.

Hibernate QuerySyntaxException: table_name is not mapped 対処

編集
この記事の要点
  • org.hibernate.hql.internal.ast.QuerySyntaxException: table_name is not mappedJPQL で実テーブル名を直接書いたエラー
  • JPQL はエンティティクラス名を使う(テーブル名ではない)
  • 対処: FROM usersFROM User u に変更
  • 実テーブル名で書きたいなら Native Query (nativeQuery = true)
  • @Entity のないクラスは JPQL で使えない

 

エラーの状況

org.hibernate.hql.internal.ast.QuerySyntaxException:
users is not mapped [SELECT u FROM users u WHERE u.email = :email]

# または
QuerySyntaxException: User is not mapped [...]

JPQL(Java Persistence Query Language)は SQL ライクですが、エンティティ名で書く必要があります。テーブル名や未登録のクラス名を書くとこのエラー。

原因と対処

原因 1: テーブル名を使った

// エンティティ定義
@Entity
@Table(name = "users")  // ← DB テーブル名は "users"
public class User { ... }

// ダメな例
@Query("SELECT u FROM users u WHERE u.email = :email")  // ← テーブル名
Optional findByEmail(@Param("email") String email);

// 修正: エンティティクラス名を使う
@Query("SELECT u FROM User u WHERE u.email = :email")  // ← クラス名 "User"
Optional findByEmail(@Param("email") String email);

原因 2: クラス名のタイポ

// エンティティ: com.example.User
@Query("SELECT u FROM Users u")  // ← typo: Users (s が余計)
List findAll();

// 修正
@Query("SELECT u FROM User u")

原因 3: @Entity が付いていない

// ダメな例
public class User {  // @Entity なし
    @Id private Long id;
    private String name;
}

@Query("SELECT u FROM User u")
// → User is not mapped

// 修正
@Entity
@Table(name = "users")
public class User { ... }

原因 4: スキャン対象外

// メインクラス
@SpringBootApplication
public class MyApp { }  // com.example パッケージ

// エンティティ
package com.other.entity;  // ← com.example の外!
@Entity
public class User { ... }

// → スキャンされず、JPA に認識されない

// 修正: パッケージスキャンに追加
@SpringBootApplication
@EntityScan(basePackages = {"com.example", "com.other"})
public class MyApp { }

原因 5: persistence.xml に未登録



    com.example.User  
    com.example.Order


# または exclude-unlisted-classes="false" で全自動スキャン

    false

JPQL vs SQL の対応

項目JPQLSQL
FROM 対象エンティティクラス名 (User)テーブル名 (users)
カラムフィールド名 (u.email)カラム名 (u.email_address)
JOINリレーション名 (u.orders)JOIN テーブル名
戻り値エンティティオブジェクトResultSet

JPQL の例

// 基本
@Query("SELECT u FROM User u WHERE u.email = :email")
Optional findByEmail(@Param("email") String email);

// JOIN
@Query("""
    SELECT o FROM Order o
    JOIN o.user u
    WHERE u.email = :email
    """)
List findOrdersByUserEmail(@Param("email") String email);

// FETCH JOIN (N+1 問題対策)
@Query("SELECT DISTINCT u FROM User u LEFT JOIN FETCH u.orders")
List findAllWithOrders();

// COUNT / 集計
@Query("SELECT COUNT(u) FROM User u WHERE u.active = true")
long countActiveUsers();

// SELECT 一部フィールド (DTO 投影)
@Query("SELECT new com.example.dto.UserSummary(u.id, u.name) FROM User u")
List findSummaries();

Native Query(テーブル名で書きたい場合)

// テーブル名・SQL 構文をそのまま使う
@Query(value = "SELECT * FROM users WHERE email = :email",
       nativeQuery = true)
Optional findByEmailNative(@Param("email") String email);

// 複雑な SQL(PostgreSQL 固有等)
@Query(value = """
    WITH user_stats AS (
        SELECT user_id, COUNT(*) AS order_count
        FROM orders
        GROUP BY user_id
    )
    SELECT u.* FROM users u
    JOIN user_stats us ON u.id = us.user_id
    WHERE us.order_count > :minCount
    """, nativeQuery = true)
List findHeavyUsers(@Param("minCount") int minCount);

// UPDATE / DELETE
@Modifying
@Query(value = "UPDATE users SET status = :status WHERE id = :id",
       nativeQuery = true)
int updateStatusNative(@Param("id") Long id, @Param("status") String status);

確認方法

登録済みエンティティ一覧

@Autowired
private EntityManagerFactory emf;

public void listEntities() {
    emf.getMetamodel().getEntities().forEach(e ->
        System.out.println(e.getName() + " → " + e.getJavaType().getName())
    );
}

// またはログ出力 (application.properties)
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

SQL の確認

# application.properties
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

# 出力例
Hibernate:
    select
        user0_.id as id1_0_,
        user0_.email as email2_0_
    from
        users user0_
    where
        user0_.email = ?

関連エラー

  • not mapped to a table: 同じく未登録エンティティ
  • Path expected for join: JOIN 構文ミス(テーブル名直接記述)
  • could not resolve property: xxx of: User: フィールド名のタイポ
  • unexpected token: select: JPQL の中で SQL の SELECT を使った

関連記事

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. java.lang.IllegalStateException: CGLIB is required to process @Configuration classes
  2. Error creating bean with name 'org.springframework.aop.config.internalAutoProxyCreator': Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize class org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
  3. No mapping found for HTTP request with URI ... in DispatcherServlet with name ...
  4. An internal error occurred during: "Building UI model". com/google/common/base/Function
  5. No identifier specified for entity : ...
  6. org.hibernate.hql.internal.ast.QuerySyntaxException: table_name is not mapped
  7. No compiler is provided in this environment
  8. java.sql.SQLException: The server time zone value ' ... ' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone
  9. Caused by: java.lang.RuntimeException: Executing an update/delete query
  10. Not supported for DML operations
  11. Field ... required a bean of type ... hat could not be found.
  12. Annotation-specified bean name ' ... ' for bean class [ ... ] conflicts with existing, non-compatible bean definition of same name and class [...]
  13. Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback.
  14. Exception in thread "main" java.lang.UnsupportedClassVersionError