1

私はテーブルユーザーを持っています


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

2番目のテーブルSpecialUsersがあります。SpecialUsersテーブルでUserIdを2回発生させることはできず、UsersテーブルのユーザーIDのごく一部のみが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") 
/

HibernateでのUsersテーブルのマッピングは問題なく機能します


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

しかし、SpecialUsersテーブルのマッピングを作成するのに苦労しています。私が見つけたインターネットのすべての例(Hibernateのドキュメントなど)には、このタイプの自己参照がありません。私はこのようなマッピングを試しました:


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

しかし、エラーが発生しました


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

SpecialUsersテーブルをどのようにマップする必要がありますか?アプリケーションレベルで必要なのは、SpecialUsersテーブルに含まれているUserオブジェクトのリストです。

4

2 に答える 2

2

SpecialUsersテーブルをどのようにマップする必要がありますか?

USERSSPECIALUSERSテーブルの構造に応じて、サブクラス階層ごとにテーブルがあり、この種の階層をHibernateでマッピングすることは完全に可能です。

まず、オブジェクトモデルレベルでからSpecialUser 継承Userすることを確認します(これは継承関係であり、自己参照ではありません)。

public class SpecialUser extends User { 
}

次に、のマッピング<joined-subclass>で要素を宣言します。User

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

アプリケーションレベルで必要なのは、SpecialUsersテーブルに含まれているUserオブジェクトのリストです。

次のHQLクエリはすべてを返しますSpecialUser(これUserも):

from SpecialUser

後でテーブルに列を追加する必要がある場合はSPECIALUSERS、対応する属性をSpecialUserクラスに追加し、それらを<joined-subclass>要素内にマップします。詳細については、(ドキュメントへの)提供されたリンクを参照してください。

于 2010-02-24T17:00:12.117 に答える
1

本当に2番目のテーブルを使用する必要がある場合は、それを新しいクラスにマップする必要があります。Hibernateは常に1つのテーブルのみを1つのクラスにマップできます。

または、「このユーザーは特別です」という列をユーザーテーブルに追加します。それがオプションでない場合は、2つのテーブルを結合して、この列をシミュレートするビューを作成します。次に、この列でユーザーを選択できます。

2つのクラスを使用する場合は、特別なユーザーのリストをロードして、アプリケーションでマッピングを行う必要があります。

[編集]多分あなたは親子関係を調べるべきです。あなたの場合、ユーザーは親であり、その役割は子です。したがって、すべてのユーザーには、異なるテーブルにマップされる0..nのロールがあります。その後、このHQLを使用できます

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

特定の役割を持つすべてのユーザーを検索します。ただし、ほとんどの場合、特定のユーザーがいて、そのユーザーに特定の役割があるかどうかを問い合わせるだけで済みます。

于 2010-02-24T15:23:41.713 に答える