休止状態:マップされていないクラス関連付け例外
-
21-09-2019 - |
質問
これを修正するのはかなり初歩的な問題であることはわかっていますが、1) 私は Hibernate に比較的慣れていないため、2) 見つけた修正はここでは適用されない (ように思われます)。
私が得ている例外は次のとおりです。
org.hibernate.MappingException: An association from the table POSTS refers to an unmapped class: com.beans.User at org.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:1285)
これは、Hibernate が自身を構成しようとしたときに発生します。
私が扱っているオブジェクトは、ユーザー、投稿 (抽象スーパークラス)、ステータス、およびコメント (投稿の具体的なサブクラス) です。それぞれは 2 つのテーブルのいずれかの Bean です。ユーザーと投稿。User オブジェクトは非常にシンプルです。ユーザーを説明する当たり障りのないフィールドがたくさんあります。同様に退屈なフィールドに加えて、ステータスとコメントには両方とも所有者 (投稿したユーザー) がいます。ステータスとコメントの違いは、ステータスにはコメントのリストを添付できますが親はありませんが、コメントには子の投稿はありませんが、親があることです(はい、これは基本的に Facebook です)。
私が読んだところによると、問題は多対 1 マッピングにあるようですが、何も問題がないようです。私が使用している 3 つの構成ファイルは次のとおりです。
hibernate.cfg.xml:
<hibernate-configuration> <session-factory> ... <!-- mapped persistence classes --> <mapping resource="User.hbm.xml" /> <mapping resource="Post.hbm.xml" /> </session-factory> </hibernate-configuration>
ユーザー.hbm.xml:
<hibernate-mapping> <class name="com.beans.User" entity-name="User" table="USERS" proxy="User"> <id name="uid" type="java.lang.Integer"> <column name="uid" /> <generator class="assigned" /> </id> ... </class> </hibernate-mapping>
Post.hbm.xml:
<hibernate-mapping>
<class name="com.beans.Post" entity-name="Post" table="POSTS" proxy="Post" abstract="true">
<id name="pid" type="java.lang.Integer">
<column name="pid" />
<generator class="assigned" />
</id>
<discriminator column="type" />
<one-to-one name="parent" class="com.beans.Post"></one-to-one>
<many-to-one name="owner" class="com.beans.User" update="false" fetch="select">
<column name="owner" />
</many-to-one>
<property name="postDate" type="java.sql.Timestamp" update="false">
<column name="post_date" />
</property>
<property name="content" type="java.lang.String" update="false">
<column name="content" />
</property>
<property name="type" type="string" update="false">
<column name="type" />
</property>
<subclass name="com.beans.Status" discriminator-value="status">
<list name="children" inverse="false" table="POSTS" lazy="true">
<key column="pid" />
<index />
<one-to-many class="com.beans.Comment" />
</list>
</subclass>
<subclass name="com.beans.Comment" discriminator-value="comment"></subclass>
</class>
</hibernate-mapping>
Status に Comment の ArrayList が含まれているという事実をどこかで指定する必要があるような気がしますが、それは Post.hbm.xml ファイルの "list" 構造を通じて暗黙的に行われないのでしょうか?
xml ファイルはクラスパス (WEB-INF/classes) に存在し、.java ファイル自体もアプリケーションから参照できます。洞察をいただければ幸いです。
解決
投稿した例外は、エンティティ名を明示的に指定したことが原因で発生します。 <class>
宣言し、それを指定しない <many-to-one>
. 。エンティティ名は 特別な属性 同じクラスに基づく異なるマッピングを区別するために使用されます。マッピングには必要ありません。
ただし、マッピングにはさらに複数の問題があります。
<one-to-one>
親のマッピングが間違っています。定義上、1 対 1 にはできませんが、 これ 投稿には親が 1 つだけありますが、別の投稿には同じ親が含まれる可能性があります (特にコメントの場合)。これにより、親の関連付けの終点は 1 対多になります。次のようにマッピングする必要があります<many-to-one>
その代わり。- コメントのリストは、そのインデックスを維持するための特別な列がない限り、実際にはリストではありません(空であるか無効であるかによって判断されません)。
<index/>
宣言)。次のようにマッピングします<bag>
その代わり。 - コメントリストは実際には inverse=true でマップする必要があります。
- それ自体は問題ではありませんが、マッピングが読みにくくなります。ネストする必要はありません。
<column>
要素;代わりにそれを属性として持つことも、列名がプロパティ名と一致する場合は完全にスキップすることもできます。同様に、どこでも update=false にしても意味がありません。投稿を更新したくない場合は、保存しないでください :-)
他のヒント
は私にとってこの問題は、プロパティを参照しようとするのではなく、それをマッピングすることによって引き起こされました。
流暢な構文では、私はこの(間違っている!)をやっていた。
mapping.References(x => x.AdvertExpiryDays).Not.Nullable();
これよりもむしろ(正解!)。
mapping.Map(x => x.AdvertExpiryDays).Not.Nullable();
AdvertExpiryDaysがint NOT実体でした。