带Hibernate的复合密钥

带Hibernate的复合密钥,hibernate,Hibernate,为了生成下一个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, rolen

为了生成下一个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文档的相关链接

在hibernate文档中查找“复合id”元素。以下内容可能至少给出了您的意图——将
id
元素替换为:

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


请注意,强烈建议您将ID设置为一个单独的类(“组件”),该类正确地实现hashCode和equals,并且可以序列化。否则,使用
session.get()
session.load()

查找对象的方法将非常笨拙,事实上可能是这样的:

<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>
<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>
现在,这将生成一个包含表
users
roles
user\u roles
的架构,现在
user\u roles
将在用户名和角色名列中有一个主键。现在,您还可以在某个地方挂起有关角色的附加信息,例如描述

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


如果必须的话,您可以使用复合ID来实现这一点,但我要说的是,这是一种痛苦,您不想因为这么简单的事情而陷入其中。

Sergio,请看本教程。可能会帮助您。

我补充了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在数据库中创建哪些表。

谢谢您的回答。我尝试使用复合id,但没有成功。我面临着类似的问题。请详细说明(或链接到源代码)为什么使用带有key元素的set不能在两列上创建复合键?谢谢现在还不清楚你的问题是什么。