タイトル: net.sf.hibernate.MappingException: Error reading resource
SEOタイトル: Hibernate MappingException Error reading resource の原因と対処
| この記事の要点 |
|
エラー全文
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 の | パッケージ階層を / 区切りで (対処2) |
| XML 構文エラー | Caused by に DocumentException | XML エディタで検証 (対処3) |
| クラス名 mismatch | | 完全修飾名で記述 (対処4) |
| DTD/XSD バージョン不一致 | 宣言 | 使用 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 で正しく指定
org.hibernate.dialect.MySQL8Dialect
com.mysql.cj.jdbc.Driver
jdbc:mysql://localhost:3306/mydb
root
secret
対処3: hbm.xml の構文確認
典型的な XML 構文ミス: 閉じタグ漏れ / 属性値のクォート漏れ / 全角スペース混入 / BOM 付き UTF-8。IDE の XML エディタで赤線が出ない状態にしてください。
対処4: クラス名は完全修飾で
...
...
...
対処5: DTD バージョン不一致
| Hibernate 版 | パッケージ | DTD |
|---|---|---|
| 2.x | net.sf.hibernate | hibernate-mapping-2.0.dtd |
| 3.x | org.hibernate | hibernate-mapping-3.0.dtd |
| 4.x - 6.x | org.hibernate | hibernate-mapping-3.0.dtd (継続) |
古い hbm.xml をそのまま新しい Hibernate に持ち込むと、DTD 不一致や非推奨タグでエラーになります。パッケージ移動が必須: net.sf.hibernate.* → org.hibernate.* を全置換。
対処6: Maven で hbm.xml を成果物に含める
src/main/resources
**/*.xml
**/*.properties
src/main/java
**/*.hbm.xml
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 orders = new HashSet<>();
}
Spring Boot なら @SpringBootApplication + @EnableJpaRepositories で自動スキャンされ、hibernate.cfg.xml も hbm.xml も不要です。
Hibernate 5 → 6 移行の注意
- パッケージ:
javax.persistence.*→jakarta.persistence.* - 古い Dialect クラス (
MySQL5Dialect等) は削除 →MySQLDialect1 つに統合 - カスタム UserType API が刷新 →
UserTypeインターフェース - 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 に & を生で書いている可能性。& にエスケープ。
Q: classpath に hbm.xml はあるのに読まれない
A: ClassLoader の問題。複数 jar 同梱で同名 hbm.xml が衝突しているとどちらが読まれるか不定。jar -tf で確認し名前を一意化。