Pergunta

Eu tenho uma mesa usuários


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

E eu tenho uma segunda tabela especialistas. Nenhum IID do usuário pode ocorrer duas vezes na tabela Specialusers, e apenas um pequeno subconjunto dos IDs dos usuários na tabela de usuários estão contidos na tabela 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") 
/

Mapeando a tabela de usuários em Hibernate funciona bem


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

Mas estou lutando para criar o mapeamento para a mesa do Specialusers. Todos os exemplos (por exemplo, documentação de hibernados) na Internet que achei que não têm esse tipo de auto-referência. Eu tentei um mapeamento assim:


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

mas obteve o erro


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

Como devo mapear a tabela de especialistas? O que eu preciso no nível do aplicativo é uma lista dos objetos do usuário contidos na tabela Specialusers.

Foi útil?

Solução

Como devo mapear a tabela de especialistas?

De acordo com a estrutura do seu USERS e SPECIALUSERS mesas, você tem um Tabela por subclasse hierarquia e É perfeitamente possível mapear esse tipo de hierarquia com hibernado.

Primeiro, certifique -se de que SpecialUser herda a partir de User No nível do modelo de objeto (essa é uma relação de herança, não uma auto-referência).

public class SpecialUser extends User { 
}

Então, declare um <joined-subclass> elemento no UserMapeamento:

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

O que eu preciso no nível do aplicativo é uma lista dos objetos do usuário contidos na tabela Specialusers.

A seguinte consulta HQL retornaria todo o SpecialUser (que são User também):

from SpecialUser

Se mais tarde você precisar adicionar colunas ao SPECIALUSERS tabela, adicione os atributos correspondentes ao SpecialUser classe e mapeá -los dentro do <joined-subclass> elemento. Consulte o link fornecido (à documentação) para obter os detalhes.

Outras dicas

Se você realmente precisar usar uma segunda tabela, deve mapeá -la para uma nova classe. O Hibernate sempre pode mapear apenas uma tabela para uma classe.

Como alternativa, adicione uma coluna à tabela de usuários que diz "esse usuário é especial". Se isso não for uma opção, crie uma visualização que une as duas tabelas e, assim, simula esta coluna. Em seguida, você pode selecionar usuários nesta coluna.

Se você seguir o caminho de duas classes, deve carregar uma lista dos usuários especiais e fazer o mapeamento em seu aplicativo.

Editar] Talvez você deva olhar para as relações entre pais e filhos. No seu caso, o usuário é o pai e seus papéis são os filhos. Portanto, todo usuário tem 0 .. N funções que são mapeadas em uma tabela diferente. Você pode então usar este HQL

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

para encontrar todos os usuários com uma determinada função. Mas na maioria das vezes, você terá um usuário específico e só precisará consultar se ela tem uma certa função.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top