Hibernate: Clases persistentes con el mismo nombre

En mis jueguecitos con Hibernate, me he tropezado con otra tontería posiblemente evidente para el que sabe un poco de Hibernate.

Hibernate, tanto si usa ficheros de mapeo hbm.xml como si usa anotaciones, tiene en cuenta el paquete de las clases para saber dónde localizarlas. En principio no hay problemas si tenemos dos clases con el mismo nombre en paquetes distintos, por ejemplo, paquete1.Persona y paquete2.Persona.

Pero sí hay un problema que hace que hibernate proteste en el arranque si tenemos dos clases persistentes con el mismo nombre y en paquetes distintos. En el lenguaje de consulta HQL (Hibernate Query Language) por defecto se usa el nombre de la clase para saber qué estamos consultando y en este caso hay dos Persona. Con un session.createQuery("from Persona") hibernate no sabe qué clase es la que queremos.  El error que sale es algo como

org.hibernate.AnnotationException: Use of the same entity name twice: Persona

org.hibernate.DuplicateMappingException: duplicate import: Persona refers to both paquete1.Persona and paquete2.Persona

Por fortuna Hibernate lo tiene contemplado. Tenemos que dar al menos a una de estas clases otro nombre de entidad para hibernate. No tenemos que cambiar el nombre de la clase, sino sólo avisar a Hibernate para que la contemple con otro nombre. Esto se hace tal que así

// Con anotaciones
@Entity(name="OtraPersona")
public class Persona {

<!– En el hbm.xml –>
<class name="paquete2.Persona" entity-name="OtraPersona" …

 

Y tenemos que tenerlo también en cuenta a la hora de hacer las asociaciones con otras tablas. Yo he probado a dejar el class="paquete1.Persona" y me ha fallado igualmente.

<one-to-many entity-name="OtraPersona" />

A la hora de trabajar con nuestro código java, usaremos

session.createQuery("from Persona")
session.createQuery("from OtraPersona")

No lo he probado, pero según la documentación esto de dar un nombre de entidad distinto podría hacerse con una única clase. Por ejemplo, si sólo tenemos paquete.Persona, podemos mapear dos veces esta clase y darle dos nombres de entidad distintos, por ejemplo, PersonaGuay y PersonaCutre. De esta forma, la misma clase Persona podríamos guardarla en una tabla PERSONA_GUAY o en la tabla PERSONA_CUTRE, decidiendo en tiempo de ejecución dónde debe ir. Supongo que este es el motivo de que en la asociación haya que poner el entity-name en vez de el class.

 

Entradas relacionadas:

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.