5.

Hibernate MappingException Error reading resource の原因と対処

編集
この記事の要点
  • MappingException: Error reading resource は Hibernate が .hbm.xml マッピング定義ファイルを読み込む際の汎用エラー
  • 主因は 4 つ: classpath に hbm.xml が無い / XML 構文不正 / 参照クラスが存在しない / DTD/XSD バージョン不一致
  • 対処: hibernate.cfg.xml<mapping resource="...hbm.xml"/> パスを確認、src/main/resources/ 配下に配置
  • Maven なら <resource> で hbm.xml をビルド成果物に含める設定が必要
  • モダン開発では .hbm.xml ではなく JPA アノテーション (@Entity) 推奨。Hibernate 5.x → 6.x 移行ではパッケージ名が org.hibernate へ変更

エラー全文

net.sf.hibernate.MappingException: Error reading resource: com/example/model/User.hbm.xml
    at net.sf.hibernate.cfg.Configuration.addResource(Configuration.java:380)
    at net.sf.hibernate.cfg.Configuration.addClass(Configuration.java:419)
    ...
Caused by: org.dom4j.DocumentException: Error on line 12 of document : ...
    at org.dom4j.io.SAXReader.read(SAXReader.java:484)
    ...

パッケージ名が net.sf.hibernate なら Hibernate 2.x 系(2005 年頃まで)。org.hibernate なら 3.x 以降です。古いプロジェクトの保守でよく遭遇します。

原因の切り分け

原因確認方法対処
hbm.xml が classpath に無いjar 解凍して User.hbm.xml の有無src/main/resources に移動 (対処1)
パス指定誤りhibernate.cfg.xml の <mapping>パッケージ階層を / 区切りで (対処2)
XML 構文エラーCaused by に DocumentExceptionXML エディタで検証 (対処3)
クラス名 mismatch<class name="...">完全修飾名で記述 (対処4)
DTD/XSD バージョン不一致<!DOCTYPE> 宣言使用 Hibernate 版に揃える (対処5)
Maven の resources プラグイン設定target/classes に hbm.xml が無いpom.xml 修正 (対処6)

対処1: hbm.xml を classpath に置く

src/
└ main/
   ├ java/
   │  └ com/example/model/User.java
   └ resources/                          <- ★ ここに置く
      ├ hibernate.cfg.xml
      └ com/example/model/User.hbm.xml   <- パッケージ階層を作る

ビルド後 (target/classes 配下):
target/classes/
├ com/example/model/User.class
├ com/example/model/User.hbm.xml         <- 同じ階層に並ぶこと
└ hibernate.cfg.xml

対処2: hibernate.cfg.xml で正しく指定

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mydb</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">secret</property>

    <!-- ★ パッケージは / 区切り、拡張子 .hbm.xml -->
    <mapping resource="com/example/model/User.hbm.xml" />
    <mapping resource="com/example/model/Order.hbm.xml" />

    <!-- アノテーション併用なら -->
    <mapping class="com.example.model.Product" />
  </session-factory>
</hibernate-configuration>

対処3: hbm.xml の構文確認

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
  <class name="com.example.model.User" table="users">
    <id name="id" type="long" column="id">
      <generator class="identity" />
    </id>
    <property name="name"  type="string" column="name"  length="100" not-null="true" />
    <property name="email" type="string" column="email" length="200" />
    <property name="createdAt" type="timestamp" column="created_at" />

    <many-to-one name="organization" column="org_id"
                 class="com.example.model.Organization" />

    <set name="orders" cascade="all" lazy="true">
      <key column="user_id" />
      <one-to-many class="com.example.model.Order" />
    </set>
  </class>
</hibernate-mapping>

典型的な XML 構文ミス: 閉じタグ漏れ / 属性値のクォート漏れ / 全角スペース混入 / BOM 付き UTF-8。IDE の XML エディタで赤線が出ない状態にしてください。

対処4: クラス名は完全修飾で

<!-- ❌ NG: パッケージ抜け -->
<class name="User" table="users">...</class>

<!-- ✅ OK: 完全修飾名 -->
<class name="com.example.model.User" table="users">...</class>

<!-- ✅ OK: hbm.xml の親要素で package 宣言してから短縮形 -->
<hibernate-mapping package="com.example.model">
  <class name="User" table="users">...</class>
</hibernate-mapping>

対処5: DTD バージョン不一致

Hibernate 版パッケージDTD
2.xnet.sf.hibernatehibernate-mapping-2.0.dtd
3.xorg.hibernatehibernate-mapping-3.0.dtd
4.x - 6.xorg.hibernatehibernate-mapping-3.0.dtd (継続)

古い hbm.xml をそのまま新しい Hibernate に持ち込むと、DTD 不一致や非推奨タグでエラーになります。パッケージ移動が必須: net.sf.hibernate.*org.hibernate.* を全置換。

対処6: Maven で hbm.xml を成果物に含める

<!-- pom.xml -->
<build>
  <resources>
    <resource>
      <directory>src/main/resources</directory>
      <includes>
        <include>**/*.xml</include>
        <include>**/*.properties</include>
      </includes>
    </resource>
    <!-- Java ソースと同じ階層に hbm.xml がある場合 -->
    <resource>
      <directory>src/main/java</directory>
      <includes>
        <include>**/*.hbm.xml</include>
      </includes>
    </resource>
  </resources>
</build>

JPA アノテーション (推奨)

新規開発では xml なし の JPA アノテーションが標準です:

@Entity
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, length = 100)
    private String name;

    @Column(length = 200)
    private String email;

    @Column(name = "created_at")
    private LocalDateTime createdAt;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "org_id")
    private Organization organization;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<Order> orders = new HashSet<>();
}

Spring Boot なら @SpringBootApplication + @EnableJpaRepositories で自動スキャンされ、hibernate.cfg.xml も hbm.xml も不要です。

Hibernate 5 → 6 移行の注意

  • パッケージ: javax.persistence.*jakarta.persistence.*
  • 古い Dialect クラス (MySQL5Dialect 等) は削除 → MySQLDialect 1 つに統合
  • カスタム UserType API が刷新 → UserType<T> インターフェース
  • Bytecode enhancement のデフォルトが変更
  • 結果として 古い hbm.xml はそのままでは動かない → JPA に移行 or hibernate-types 利用

FAQ

Q: Eclipse からは動くが mvn package すると失敗する
A: Eclipse が src/main/java の hbm.xml を classpath に含めてしまっているケース。Maven 側で resources プラグインに含めるか、resources ディレクトリに移動する。

Q: 「The reference to entity must end with the ";" delimiter」と出る
A: hbm.xml に & を生で書いている可能性。&amp; にエスケープ。

Q: classpath に hbm.xml はあるのに読まれない
A: ClassLoader の問題。複数 jar 同梱で同名 hbm.xml が衝突しているとどちらが読まれるか不定。jar -tf で確認し名前を一意化。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. ids for this class must be manually assigned before calling save()
  2. Number of positional parameter types (1 does not match number of positional parameters (2)
  3. net.sf.hibernate.MappingException: No persister for ~
  4. net.sf.hibernate.QueryException: unexpected token: as [~]
  5. net.sf.hibernate.MappingException: Error reading resource
  6. IllegalArgumentException occurred while calling setter of

最近更新/作成されたページ