2009-10-14 10 views
8

So che questo dovrebbe essere un problema piuttosto elementare da risolvere, ma 1) Sono relativamente nuovo a Hibernate e 2) le correzioni che ho trovato non sembrano (sembrano) applicare qui .Ibernazione: eccezione associazione classe non mappata

Ecco l'eccezione sto ottenendo:

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)

Ciò si verifica quando Hibernate tenta di configurare se stessa.

Gli oggetti con cui sto lavorando sono Utenti, Post (superclasse astratta), Status e Commenti (sottoclassi concrete di Post). Ciascuno è un bean di una delle due tabelle: USERS e POSTS. Gli oggetti User sono piuttosto vanilla: molti campi blandi che descrivono l'utente. Oltre ai campi noiosamente simili, uno stato e un commento hanno entrambi i proprietari (utente che lo ha pubblicato). Ciò che distingue uno stato da un commento è che uno stato può avere un elenco di commenti ad esso allegato ma nessun genitore, mentre un commento non ha post per bambini, ma ha un genitore (sì, questo è fondamentalmente Facebook).

Da quello che ho letto, il problema sembra essere nei mapping molti-a-uno, ma non riesco a trovare nulla di sbagliato. Ecco i tre file di configurazione che sto utilizzando.

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> 

ho la sensazione che ho bisogno di specificare da qualche parte il fatto che uno Status contiene un ArrayList di Comment, ma non è quello fatto implicitamente attraverso il costrutto "list" nel Post.hbm.xml f ile?

I file xml esistono nel mio classpath (WEB-INF/classes), e anche i file .java sono visibili all'applicazione. Le intuizioni sarebbero apprezzate!

risposta

17

L'eccezione che hai postato è causata da te specificando esplicitamente un nome di entità sulla dichiarazione <class> e non specificandola su <many-to-one>. Il nome dell'entità è un special attribute utilizzato per distinguere tra diversi mapping basati sulla stessa classe. NON ne hai bisogno per la tua mappatura.

Detto questo, ci sono più problemi supplementari con la mappatura:

  1. <one-to-one> mappatura per il genitore è sbagliato. Non può essere uno a uno per definizione - mentre il questo post avrà un solo genitore, un altro post potrebbe avere lo stesso genitore (specialmente per i commenti) che rende uno dei due genitore di fine associazione uno-a-molti. Devi invece mapparlo come <many-to-one>.
  2. L'elenco di commenti non è realmente un elenco a meno che non si disponga di una colonna speciale per mantenere l'indice (che non si giudica mediante dichiarazione vuota - e non valida - <index/>). Mappalo come <bag> invece.
  3. La lista di commenti dovrebbe essere mappata con inverse = true.
  4. Non è un problema di per sé, ma rende la mappatura più difficile da leggere: non è necessario inserire l'elemento nidificato <column>; puoi averlo come attributo o saltarlo del tutto se il nome della colonna corrisponde al nome della proprietà.Allo stesso modo, se non vuoi aggiornare i tuoi post, non li salvo :-)
+2

Wow, grazie mille! È evidente che ho ancora un po 'da imparare su questo framework, poiché dopo aver seguito i tuoi suggerimenti, ho dovuto gestire sequenzialmente almeno una dozzina di nuove eccezioni dall'incombenza di altri aspetti della mia configurazione di Hibernate. Questa volta i miei errori sono stati più semplici e tutto sembra funzionare :) È la mia prima applicazione alimentata da Hibernate e respira dopo soli tre giorni di apprendimento! Grazie mille per il tuo aiuto! – Magsol

+3

Sei il benvenuto e buona fortuna con Hibernate. All'inizio diventa un po 'difficile, ma dopo un po' diventa una seconda natura. E il fatto che sei riuscito a farlo funzionare dopo solo 3 giorni fa pensare che non avrai troppi problemi andando avanti :-) – ChssPly76

2

Per me questo problema è stato causato dal tentativo di fare riferimento a una proprietà piuttosto che mappare esso.

In sintassi fluente stavo facendo questo (sbagliato!).

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

Piuttosto che questo (corretto!).

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

Dove AdvertExpiryDays era un'int NOT un'entità.

Problemi correlati