Pregunta

Tengo usuarios de una mesa


CREATE TABLE "USERS" (
    "ID" NUMBER NOT NULL ,
    "LOGINNAME" VARCHAR2 (150) NOT NULL )

Y tengo una segunda mesa especialistas. No puede ocurrir un IID de usuario dos veces en la tabla de especialusadores, y solo un pequeño subconjunto de los ID de los usuarios en la tabla de usuarios está contenido en la tabla de especialistas.


CREATE TABLE "SPECIALUSERS" (
    "USERID" NUMBER NOT NULL,
 CONSTRAINT "PK_SPECIALUSERS" PRIMARY KEY ("USERID") )

ALTER TABLE "SPECIALUSERS" ADD CONSTRAINT "FK_SPECIALUSERS_USERID" FOREIGN KEY ("USERID") 
REFERENCES "USERS" ("ID") 
/

Mapear la mesa de los usuarios en Hibernate funciona bien


<hibernate-mapping package="com.initech.domain">
    <class name="com.initech.User" table="USERS">

        <id name="id" column="ID" type="java.lang.Long">
            <meta attribute="use-in-tostring">true</meta>
            <generator class="sequence">
                <param name="sequence">SEQ_USERS_ID</param>
            </generator>
        </id>

        <property name="loginName" column="LOGINNAME" type="java.lang.String" not-null="true">
            <meta attribute="use-in-tostring">true</meta>
        </property>

    </class>
</hibernate-mapping>

Pero estoy luchando en crear el mapeo para la mesa de los especialistas. Todos los ejemplos (por ejemplo, en documentación de hibernación) en Internet, encontré que no tienen este tipo de autorreferencia. Intenté un mapeo como este:


<hibernate-mapping package="com.initech.domain">
    <class name="com.initech.User" table="SPECIALUSERS">        

        <id name="id" column="USERID">
            <meta attribute="use-in-tostring">true</meta>
            <generator class="foreign">
                <param name="property">user</param>
            </generator>
        </id>

        <one-to-one name="user" class="User"/>

    </class>
</hibernate-mapping>

Pero recibí el error


Invocation of init method failed; nested exception is org.hibernate.DuplicateMappingException: 
Duplicate class/entity mapping com.initech.User 

¿Cómo debo mapear la mesa de los especialistas? Lo que necesito en el nivel de aplicación es una lista de los objetos de usuario contenidos en la tabla de especialusores.

¿Fue útil?

Solución

¿Cómo debo mapear la mesa de los especialistas?

Según la estructura de su USERS y SPECIALUSERS tablas, tienes un Mesa por subclase jerarquía y Es perfectamente posible mapear este tipo de jerarquía con hibernado.

Primero, asegúrese de que SpecialUser hereda de User A nivel de modelo de objeto (esta es una relación de herencia, no una autorreferencia).

public class SpecialUser extends User { 
}

Entonces, declara un <joined-subclass> elemento en el Usermapeo:

<hibernate-mapping package="com.initech.domain">
    <class name="com.initech.User" table="USERS">

        <id name="id" column="ID" type="java.lang.Long">
            <meta attribute="use-in-tostring">true</meta>
            <generator class="sequence">
                <param name="sequence">SEQ_USERS_ID</param>
            </generator>
        </id>

        <property name="loginName" column="LOGINNAME" type="java.lang.String" not-null="true">
            <meta attribute="use-in-tostring">true</meta>
        </property>

        <joined-subclass name="com.initech.SpecialUser" table="SPECIALUSERS">
            <key column="USERID"/>
        </joined-subclass>

    </class>
</hibernate-mapping>

Lo que necesito en el nivel de aplicación es una lista de los objetos de usuario contenidos en la tabla de especialusores.

La siguiente consulta de HQL devolvería toda la SpecialUser (que son User también):

from SpecialUser

Si más tarde necesita agregar columnas al SPECIALUSERS tabla, agregue los atributos correspondientes al SpecialUser clasificarlos y asignarlos dentro del <joined-subclass> elemento. Consulte el enlace proporcionado (a la documentación) para obtener los detalles.

Otros consejos

Si realmente tiene que usar una segunda tabla, debe asignarla a una nueva clase. Hibernate siempre puede mapear una mesa a una clase.

Alternativamente, agregue una columna a la tabla de usuario que dice "este usuario es especial". Si esa no es una opción, cree una vista que une las dos tablas y, por lo tanto, simula esta columna. Luego, puede seleccionar usuarios por esta columna.

Si sigue la clase de dos clases, debe cargar una lista de los usuarios especiales y hacer la asignación en su aplicación.

Editar] Tal vez deberías investigar las relaciones entre padres e hijos. En su caso, el usuario es el padre y sus roles son los niños. Entonces, cada usuario tiene roles 0..n que se asignan en una tabla diferente. Entonces puedes usar este HQL

from User u where :role in elements(u.roles)

para encontrar a todos los usuarios con un cierto rol. Pero la mayoría de las veces, tendrá un usuario específico y solo necesitará consultar si tiene un cierto papel.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top