Hibernate: Exceção de associação de classe não mapeada
-
21-09-2019 - |
Pergunta
Sei que esse deve ser um problema bastante elementar a ser corrigido, mas 1) sou relativamente novo no Hibernate e 2) as correções que encontrei não (parecem) se inscrever aqui.
Aqui está a exceção que estou recebendo:
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)
Isso ocorre quando o hibernato tenta se configurar.
Os objetos com os quais estou trabalhando são usuários, postagens (superclasse abstrata), status e comentários (subclasses concretas da postagem). Cada um é Bean de uma das duas tabelas: usuários e postagens. Os objetos do usuário são bastante baunilha: muitos campos brandos descrevendo o usuário. Além de campos igualmente chatos, um status e um comentário têm proprietários (usuário que o publicou). O que diferencia um status de um comentário é que um status pode ter uma lista de comentários anexados a ele, mas nenhum pai, enquanto um comentário não tem postagens para crianças, mas tem um pai (sim, isso é basicamente no Facebook).
Pelo que li, o problema parece estar nos mapeamentos muitos para um, mas não consigo encontrar nada de errado. Aqui estão os três arquivos de configuração que estou 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>
Tenho a sensação de que preciso especificar em algum lugar o fato de que um status contém um ArrayList of Comment's, mas isso não é feito implicitamente através da construção "Lista" no arquivo post.hbm.xml?
Os arquivos XML existem no meu ClassPath (Web-Inf/Classes) e os próprios arquivos .java também são visíveis para o aplicativo. As idéias seriam apreciadas!
Solução
A exceção que você postou é causada por você especificando explicitamente um nome de entidade em <class>
declaração e não especificando <many-to-one>
. O nome da entidade é um atributo especial usado para distinguir entre diferentes mapeamentos com base na mesma classe. Você não precisa disso para o mapeamento.
Dito isto, existem vários problemas adicionais com o seu mapeamento:
<one-to-one>
O mapeamento para os pais está errado. Não pode ser individual por definição-enquanto isto A postagem terá apenas um dos pais, outro post pode ter o mesmo pai (especialmente para comentários), o que torna o fim da associação dos pais um para muitos. Você precisa mapeá -lo como<many-to-one>
em vez de.- A lista de comentários não é realmente uma lista, a menos que você tenha uma coluna especial para manter seu índice (que você não julgou por vazio - e inválido -
<index/>
declaração). Mapeá -lo como<bag>
em vez de. - A lista de comentários realmente deve ser mapeada com inverso = true.
- Não é um problema em si, mas torna seu mapeamento mais difícil de ler - não há necessidade de aninhado
<column>
elemento; Você pode tê -lo como atributo ou ignorá -lo se o nome da coluna corresponder ao nome da propriedade. Da mesma forma, não há sentido em ter atualização = false em todos os lugares - se você não deseja que suas postagens sejam atualizadas, não as salve :-)
Outras dicas
Para mim, esse problema foi causado pela tentativa de fazer referência a uma propriedade em vez de mapeá -la.
Na sintaxe fluente, eu estava fazendo isso (errado!).
mapping.References(x => x.AdvertExpiryDays).Not.Nullable();
Em vez disso (correto!).
mapping.Map(x => x.AdvertExpiryDays).Not.Nullable();
Onde o Advertexpirydays era uma entidade.