2009-10-14 14 views
8

Sé que esto debería ser un problema bastante elemental para solucionar, pero 1) Soy relativamente nuevo en Hibernate, y 2) las soluciones que he encontrado no parecen (parece) aplicar aquí .Hibernate: excepción de asociación de clase no asignada

Aquí es la excepción que estoy recibiendo:

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)

Esto ocurre cuando Hibernate intenta configurarse a sí mismo.

Los objetos con los que estoy trabajando son Usuarios, Publicaciones (superclase abstracta), Estados y Comentarios (subclases concretas de Publicaciones). Cada uno es frijol de una de dos tablas: USUARIOS y POSTES. Los objetos de usuario son bastante vanidosos: muchos campos insípidos que describen al usuario. Además de los campos aburridos de manera similar, un Estado y un Comentario tienen propietarios (Usuario que lo publicó). Lo que diferencia un estado de un comentario es que un estado puede tener una lista de comentarios adjunta, pero no un padre, mientras que un comentario no tiene mensajes secundarios, pero tiene un padre (sí, esto es básicamente Facebook).

Por lo que he leído, el problema parece estar en las asignaciones de varios a uno, pero parece que no puedo encontrar nada mal. Aquí están los tres archivos de configuración que estoy usando.

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> 

tengo la sensación de que necesito especifique en alguna parte el hecho de que un Estado contiene una Lista de Arreglos de Comentarios, pero no se hace eso implícitamente a través de la construcción "lista" en el Post.hbm.xml f ile?

Los archivos xml existen en mi classpath (WEB-INF/classes), y los propios archivos .java también son visibles para la aplicación. ¡Las apreciaciones serán apreciadas!

Respuesta

17

La excepción que ha publicado se debe a que especifica explícitamente un nombre de entidad en la declaración <class> y no lo especifica en <many-to-one>. El nombre de la entidad es special attribute utilizado para distinguir entre diferentes asignaciones basadas en la misma clase. NO lo necesitas para tu mapeo.

Dicho esto, hay varios problemas adicionales con su asignación:

  1. <one-to-one> mapeo para los padres es erróneo. No puede ser uno-a-uno por definición, mientras que esta publicación solo tendrá un padre, otra publicación puede tener ese mismo padre (especialmente para comentarios) lo que hace que el extremo de la asociación de padres sea uno a muchos. En su lugar, debe asignarlo como <many-to-one>.
  2. La lista de comentarios no es realmente una lista a menos que tenga una columna especial para mantener su índice (que no juzga por vacío - y no válido - <index/> declaración). Asígnelo como <bag>.
  3. La lista de comentarios realmente debe asignarse con inverso = verdadero.
  4. No es un problema per se, pero hace que su mapeo sea más difícil de leer, no hay necesidad de un elemento anidado <column>; puede tenerlo como atributo en su lugar u omitirlo por completo si el nombre de la columna coincide con el nombre de la propiedad.Del mismo modo, no tiene sentido actualizar = falso en todas partes. Si no quiere que se actualicen sus publicaciones, no las guarde :-)
+2

¡Guau, muchas gracias! Es evidente que aún tengo bastante que aprender sobre este marco, ya que después de seguir sus sugerencias, tuve que manejar secuencialmente al menos una docena de nuevas excepciones para evitar otros aspectos de la configuración de Hibernate. Esta vez mis errores fueron más simples, y todo parece estar funcionando :) ¡Es mi primera aplicación Hibernate y respira después de solo tres días de aprendizaje! ¡Muchas gracias por su ayuda! – Magsol

+3

De nada y la mejor de las suertes con Hibernate. Al principio es un poco difícil pero se convierte en una segunda naturaleza después de un tiempo. Y el hecho de que hayas logrado que funcione después de solo 3 días sugiere que no tendrás muchos problemas en el futuro :-) – ChssPly76

2

Para mí, este problema fue causado al intentar hacer referencia a una propiedad en lugar de mapear eso.

En sintaxis fluida estaba haciendo esto (¡mal!).

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

En lugar de esto (¡correcto!).

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

Donde AdvertExpiryDays was an int NO una entidad.

Cuestiones relacionadas