Question

I know this should be a pretty elementary issue to fix, but 1) I'm relatively new to Hibernate, and 2) the fixes I've found don't (seem to) apply here.

Here is the exception I am getting:

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)

This occurs when Hibernate attempts to configure itself.

The objects I'm working with are Users, Posts (abstract superclass), Statuses and Comments (concrete subclasses of Post). Each is bean from one of two tables: USERS and POSTS. The User objects are pretty vanilla: lots of bland fields describing the user. In addition to similarly boring fields, a Status and a Comment both have owners (User that posted it). What differentiates a Status from a Comment is that a Status can have a list of Comments attached to it but no parent, while a Comment has no children posts, but has a parent (yes, this is basically Facebook).

From what I've read, the problem seems to be in the many-to-one mappings, but I can't seem to find anything wrong. Here are the three configuration files I'm using.

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>

I get the feeling I need to specify somewhere the fact that a Status contains an ArrayList of Comment's, but isn't that done implicitly through the "list" construct in the Post.hbm.xml file?

The xml files exist in my classpath (WEB-INF/classes), and the .java files themselves are visible to the application as well. Insights would be appreciated!

Was it helpful?

Solution

The exception you've posted is caused by you explicitly specifying an entity name on <class> declaration and not specifying it on <many-to-one>. Entity name is a special attribute used for distinguishing between different mappings based on the same class. You do NOT need it for you mapping.

That said, there are multiple additional issues with your mapping:

  1. <one-to-one> mapping for parent is wrong. It can't be one-to-one by definition - while this post will only have one parent, another post may have that same parent (especially for comments) which makes parent's end of association one-to-many. You need to map it as <many-to-one> instead.
  2. List of comments is not really a list unless you have a special column to maintain its index (which you don't judging by empty - and invalid - <index/> declaration). Map it as <bag> instead.
  3. Comment list really should be mapped with inverse=true.
  4. Not a problem per se but it makes your mapping harder to read - there's no need for nested <column> element; you can have it as attribute instead or skip it altogether if column name matches property name. Similarly, no point in having update=false everywhere - if you don't want your posts updated, don't save them :-)

OTHER TIPS

For me this issue was caused by trying to reference a property rather than mapping it.

In fluent syntax I was doing this (wrong!).

mapping.References(x => x.AdvertExpiryDays).Not.Nullable();

Rather than this (correct!).

mapping.Map(x => x.AdvertExpiryDays).Not.Nullable();

Where AdvertExpiryDays was an int NOT an entity.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top