在Hibernate中映射两个表0..n

时间:2010-02-24 15:16:04

标签: java hibernate orm mapping one-to-one

我有一个表用户


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

我有第二张桌子SpecialUsers。在UserUsers表中没有UserId可以出现两次,并且在Users表中只包含一小部分用户ID。


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表创建映射。我发现的Internet中的所有示例(例如在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对象列表。

2 个答案:

答案 0 :(得分:2)

  

我应该如何映射SpecialUsers表?

根据您的USERSSPECIALUSERS表的结构,您有一个Table per subclass层次结构,完全有可能使用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>元素中。有关详细信息,请参阅提供的链接(文档)。

答案 1 :(得分:1)

如果您真的必须使用第二个表,则必须将其映射到新类。 Hibernate总是只能将一个表映射到一个类。

或者,在用户表中添加一列“此用户特殊”。如果这不是一个选项,请创建一个连接两个表的视图,从而模拟此列。然后,您可以按此列选择用户。

如果你采用两种方法,你必须加载一个特殊用户列表并在你的应用程序中进行映射。

[编辑]也许你应该研究亲子关系。在您的情况下,用户是父级,其角色是子级。因此每个用户都有0..n个角色,这些角色映射在不同的表中。然后,您可以使用此HQL

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

查找具有特定角色的所有用户。但大多数情况下,你会有一个特定的用户,只需询问她是否有某个角色。

相关问题