代码之家  ›  专栏  ›  技术社区  ›  simon

在休眠状态下映射两个表0..n

  •  1
  • simon  · 技术社区  · 14 年前

    我有一个桌子使用者

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

    我还有第二张桌子,特别用户。在specialusers表中不能出现两次userid,并且specialusers表中只包含用户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中映射用户表工作正常

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

    但是我正在为特殊用户表创建映射。我发现互联网上的所有例子(例如在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表中的用户对象列表。

    2 回复  |  直到 14 年前
        1
  •  2
  •   Pascal Thivent    14 年前

    我应该如何映射SpecialUsers表?

    根据你的结构 USERS SPECIALUSERS 桌子,你有一个 Table per subclass 层次结构和 用Hibernate映射这种层次结构是完全可能的。 .

    首先,确保 SpecialUser 继承 User 在对象模型级别(这是继承关系,而不是自引用)。

    public class SpecialUser extends User { 
    }
    

    然后,声明一个 <joined-subclass> 元素在 用户 的映射:

    <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表中的用户对象列表。

    下面的hql查询将返回 特殊用户 (哪些是 用户 同样):

    from SpecialUser
    

    如果以后需要将列添加到 特殊用户 表中,将相应的属性添加到 特殊用户 类并将它们映射到 <联接子类> 元素。有关详细信息,请参阅提供的链接(到文档)。

        2
  •  1
  •   Aaron Digulla    14 年前

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

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

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

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

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

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