Впадать в спящий режим:исключение несопоставленной ассоциации классов
-
21-09-2019 - |
Вопрос
Я знаю, что это должно быть довольно элементарной проблемой для исправления, но 1) Я относительно новичок в гибернации, и 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 пытается настроить себя.
Объекты, с которыми я работаю, - это Пользователи, Записи (абстрактный суперкласс), Статусы и комментарии (конкретные подклассы Post).Каждый из них является компонентом из одной из двух таблиц:ПОЛЬЗОВАТЕЛИ и СООБЩЕНИЯ.Пользовательские объекты довольно ванильные:множество невыразительных полей, описывающих пользователя.В дополнение к таким же скучным полям, у Статуса и Комментария есть владельцы (Пользователь, разместивший его).Что отличает статус от комментария, так это то, что к статусу может быть прикреплен список комментариев, но не родительский, в то время как у комментария нет дочерних записей, но есть родительский (да, по сути, это Facebook).
Из того, что я прочитал, проблема, похоже, заключается в сопоставлениях "много к одному", но, похоже, я не могу найти ничего неправильного.Вот три файла конфигурации, которые я использую.
hibernate.cfg.xml:
<hibernate-configuration> <session-factory> ... <!-- mapped persistence classes --> <mapping resource="User.hbm.xml" /> <mapping resource="Post.hbm.xml" /> </session-factory> </hibernate-configuration>
User.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>
У меня такое чувство, что мне нужно где-то указать тот факт, что статус содержит ArrayList комментариев, но разве это не делается неявно через конструкцию "list" в файле Post.hbm.xml?
XML-файлы существуют в моем пути к классам (WEB-INF/classes), и сами JAVA-файлы также видны приложению.Идеи были бы оценены по достоинству!
Решение
Опубликованное вами исключение вызвано тем, что вы явно указали имя объекта на <class>
декларации и не указывая ее на <many-to-one>
.Имя объекта - это особый атрибут используется для различения различных отображений, основанных на одном и том же классе.Вам ЭТО НЕ нужно для вашего картографирования.
Тем не менее, существует множество дополнительных проблем с вашим отображением:
<one-to-one>
отображение для parent неверно.Это не может быть один к одному по определению - в то время как это сообщение будет иметь только одного родителя, у другого сообщения может быть тот же родитель (особенно для комментариев), что делает родительский конец ассоциации "один ко многим".Вам нужно отобразить это как<many-to-one>
вместо этого.- Список комментариев на самом деле не является списком, если у вас нет специального столбца для поддержания его индекса (который вы не используете, судя по пустому и недопустимому -
<index/>
декларация).Отобразите это как<bag>
вместо этого. - Список комментариев действительно должен быть сопоставлен с inverse=true .
- Само по себе это не проблема, но это затрудняет чтение вашего отображения - нет необходимости во вложенных
<column>
элемент;вы можете использовать его вместо этого в качестве атрибута или вообще пропустить, если имя столбца совпадает с именем свойства.Аналогично, нет смысла везде устанавливать update = false - если вы не хотите, чтобы ваши сообщения обновлялись, не сохраняйте их :-)
Другие советы
Для меня эта проблема была вызвана попыткой ссылаться на свойство, а не сопоставлять его.
В fluent syntax я делал это (неправильно!).
mapping.References(x => x.AdvertExpiryDays).Not.Nullable();
Вместо этого (правильно!).
mapping.Map(x => x.AdvertExpiryDays).Not.Nullable();
Где AdvertExpiryDays был int, А НЕ сущностью.