【问题标题】:Composite Key with HibernateHibernate 的复合键
【发布时间】:2009-04-15 13:08:48
【问题描述】:

为了生成下一个SQL代码:

create table users (
    user_name varchar(15) not null primary key, 
    user_pass varchar(15) not null);

create table user_roles(
    username varchar(15) not null,
    role_name varchar(15) not null, 
    primary key(usernmae, rolename)
);

你可以使用如下代码:

 <?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="databaselayer.users.UserDB" table="users">
        <id name="username" type="string" column="user_name">
                <meta attribute="scope-set">public</meta>      
        </id>    
        <property name="password" type="string" column="user_pass"  not-null="true"/>
        <set name="roles" cascade="save-update" inverse="true">
                <key column="user_name"/>
                <one-to-many class="databaselayer.users.RoleDB"/>
        </set>                       
    </class>
   <class name="databaselayer.users.RoleDB" table="user_roles">
        <composite-id>
            <key-many-to-one name="username" class="databaselayer.users.UserDB" column="user_name"/>
            <key-property name="role" type="string" column="role_name"/>
        </composite-id>             
    </class>          
</hibernate-mapping>

您可能需要在您的类路径中包含您的类以及 hbm 映射文件。
接下来我发布我的 Ant 架构目标:
注意 ${basedir}/build/WEB-INF/classes 包含 *.class 和 *.hbm.xml 文件。

<target name="schema" description="Generate DB schema from the O/R mapping files">
    <hibernatetool destdir="${basedir}">            
        <classpath path="${basedir}/build/WEB-INF/classes">
            <fileset dir="${basedir}/build/WEB-INF/classes">
            <include name="**/*"/>
        </fileset>              
        </classpath>
        <configuration configurationfile="${basedir}/hibernate.cfg.xml"/>
        <hbm2ddl 
            drop="true" 
            create="true"
            export="true"
            outputfilename="libamo2-ddl.sql"
            delimiter=";"
            format="true"/>       
    </hibernatetool>
</target>

Hibernate 文档中的相关链接

Composite ID
Components as composite Id

【问题讨论】:

  • 不清楚你的问题是什么。

标签: hibernate


【解决方案1】:

在 hibernate 文档中查找“composite-id”元素。以下内容至少可以为您提供意图 - 将您的 id 元素替换为:

<composite-id>
    <key-property name="username"/>
    <key-property name="role"/>
</composite-id>

请注意,强烈建议将您的 ID 改为一个单独的类(“组件”),该类可以正确实现 hashCode 和 equals,并且是可序列化的。否则,使用session.get()session.load() 查找对象的方式将非常尴尬。

【讨论】:

  • 感谢您的回答。我曾尝试使用复合 ID,但没有成功。
【解决方案2】:

我添加了 Chris Winters 的答案,但使用外键来实现它。你可以写:

<composite-id>
    <key-many-to-one name="username" class="com.foo.User" />
    <key-many-to-one name="role_id" class="com.foo.Role" />
</composite-id>

这将完成这项工作并处理外键,并使您可以灵活地自行定义 Hibernate 在数据库中创建哪些表。

【讨论】:

    【解决方案3】:

    实际上可能是这样的:

    <class name="User" table="users">
      <id name="username" column="user_name"/>
      <property name="password" column="user_pass" not-null="true"/>
      <set name="roles" table="user_roles">
        <key column="user_name"/>
        <element type="string" column="role_name" />
      </set>
    </class>
    

    这会将角色映射到 User 类中的集合,并大致匹配您提供的架构。但它不会在 user_roles 的列中生成主键。

    不过,您通常会通过更规范化的模式从 Hibernate 中获得更好的结果。例如,在这种情况下,您没有角色本身的表;但是您似乎所描述的内容很自然地被建模为 User 和 Role 类,它们之间具有多对多的关系。像这样的:

    <class name="User" table="users">
      <id name="username" column="user_name"/>
      <property name="password" column="user_pass" not-null="true"/>
      <set name="roles" table="user_roles">
        <key column="user_name"/>
        <many-to-many column="role_name" class="Role"/>
      </set>
    </class>
    <class name="Role" table="roles">
      <id name="name" column="role_name"/>
    </class>
    

    现在这将生成一个包含表usersrolesuser_roles 的架构,现在user_roles 将在用户名和角色名列中拥有一个主键。您现在还可以在某个地方挂起有关角色的其他信息,例如描述。

    此外,您发布的错误是 ClassNotFoundException,这似乎不太可能是您的映射的实际问题。

    如果必须的话,您可以使用复合 ID 来执行此操作,但我想说,您只是不想因为这么简单的事情而陷入困境。

    【讨论】:

    • 我遇到了类似的问题。您能否详细说明(或链接到来源)为什么使用带有键元素的集合,不会在两列上创建复合键?谢谢!
    【解决方案4】:

    Sergio,看看这个composite key mapping in hibernate 教程。或许能帮到你。

    【讨论】:

      猜你喜欢
      • 2015-05-25
      • 2012-03-18
      • 1970-01-01
      • 1970-01-01
      • 2015-09-28
      • 1970-01-01
      • 2018-01-07
      • 1970-01-01
      相关资源
      最近更新 更多