Domanda

Ho una tabella Utenti


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

e ho una seconda tabella SpecialUsers.Nessun UserId può essere presente due volte nella tabella SpecialUsers e solo un piccolo sottoinsieme degli ID degli utenti nella tabella Users è contenuto nella tabella SpecialUsers.


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") 
/

La mappatura della tabella Users in Hibernate funziona bene


<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>

Ma ho difficoltà a creare la mappatura per la tabella SpecialUsers.Tutti gli esempi (es.nella documentazione di Hibernate) in Internet ho scoperto che non hanno questo tipo di autoreferenzialità.Ho provato una mappatura come questa:


<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>

ma ho ricevuto l'errore


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

Come devo mappare la tabella SpecialUsers?Ciò di cui ho bisogno a livello applicativo è un elenco degli oggetti User contenuti nella tabella SpecialUsers.

È stato utile?

Soluzione

Come devo mappare la tabella SpecialUsers?

Secondo la struttura del tuo USERS E SPECIALUSERS tavoli, hai un Tabella per sottoclasse gerarchia e è perfettamente possibile mappare questo tipo di gerarchia con Hibernate.

Per prima cosa, assicurati che SpecialUser eredita da User a livello del modello a oggetti (si tratta di una relazione di ereditarietà, non di autoreferenzialità).

public class SpecialUser extends User { 
}

Quindi dichiarare a <joined-subclass> elemento in Userla mappatura di:

<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>

Ciò di cui ho bisogno a livello applicativo è un elenco degli oggetti User contenuti nella tabella SpecialUsers.

La seguente query HQL restituirebbe tutti i file SpecialUser (quali sono User pure):

from SpecialUser

Se in seguito è necessario aggiungere colonne al file SPECIALUSERS tabella, aggiungi gli attributi corrispondenti alla tabella SpecialUser class e mapparli all'interno del file <joined-subclass> elemento.Fare riferimento al collegamento fornito (alla documentazione) per i dettagli.

Altri suggerimenti

Se è davvero necessario utilizzare una seconda tabella, è necessario associare ad una nuova classe. Hibernate può sempre mappare solo una tabella ad una classe.

In alternativa, aggiungere una colonna alla tabella utente che dice "questo utente è speciale". Se questo non è un'opzione, creare una vista che unisce le due tabelle e simula questa colonna in tal modo. Quindi, è possibile selezionare gli utenti da questa colonna.

Se si va il modo in due classi, è necessario caricare un elenco di utenti speciali e fare la mappatura nell'applicazione.

[EDIT] Forse si dovrebbe guardare in relazioni padre-figlio. Nel tuo caso, l'utente è il capogruppo e le sue funzioni sono i figli. Quindi, ogni utente ha 0..n ruoli che sono mappati in una tabella diversa. È quindi possibile utilizzare questo HQL

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

per trovare tutti gli utenti con un certo ruolo. Ma la maggior parte del tempo, avrete un utente specifico e solo bisogno di interrogare se ha un certo ruolo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top