Hibernate: исключение не сопоставленной ассоциации классов
Я знаю, что это должна быть довольно элементарная проблема, которую нужно исправить, но 1) я относительно новичок в Hibernate, и 2) исправления, которые я нашел, здесь (кажется) не применяются.
Вот исключение, которое я получаю:
org.hibernate.MappingException: ассоциация из таблицы POSTS относится к не отображенный класс: com.beans.User at org.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:1285)
Это происходит, когда Hibernate пытается настроить себя.
Объектами, с которыми я работаю, являются Users, Posts (абстрактный суперкласс), Status и Comments (конкретные подклассы Post). Каждый - бин из одной из двух таблиц: ПОЛЬЗОВАТЕЛИ и ПОСТЫ. Объекты User довольно ванильны: множество мягких полей, описывающих пользователя. В дополнение к таким же скучным полям, Status и Comment оба имеют владельцев (Пользователь, который их опубликовал). Что отличает статус от комментария, так это то, что к статусу может быть прикреплен список комментариев, но нет родителя, в то время как у комментария нет дочерних сообщений, но есть родитель (да, это в основном Facebook).
Из того, что я прочитал, проблема, похоже, заключается в отображении "многие к одному", но я не могу найти что-то неправильное. Вот три файла конфигурации, которые я использую.
hibernate.cfg.xml:
<Спящий режим-конфигурацию> <Сеанс завод>...Сессии завод> Спящий режим-конфигурации>
User.hbm.xml:
<Зимуют-отображение><генератор класса = "назначен" /> ID>... Класс> Отображение гибернации->
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 содержит ArrayList of Comment's, но не выполняется ли это неявно с помощью конструкции "list" в файле Post.hbm.xml?
Файлы xml существуют в моем пути к классам (WEB-INF/classes), и сами файлы.java также видны приложению. Выводы будут оценены!
2 ответа
Исключение, которое вы опубликовали, вызвано тем, что вы явно указали имя объекта в <class>
декларация и не указывать его на <many-to-one>
, Имя объекта - это специальный атрибут, используемый для различения разных отображений, основанных на одном и том же классе. Вам НЕ нужно это для картографирования.
Тем не менее, есть несколько дополнительных проблем с вашим отображением:
<one-to-one>
отображение для родителя неверно. Он не может быть однозначным по определению - хотя у этого поста будет только один родитель, у другого поста может быть тот же родитель (особенно для комментариев), что делает конец ассоциации родителя один-ко-многим. Вы должны отобразить это как<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, а не сущностью.