为了生成下一个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>
答案 0 :(得分:7)
在hibernate docs中查找'composite-id'元素。以下内容至少可以为您提供意图 - 将您的id
元素替换为:
<composite-id>
<key-property name="username"/>
<key-property name="role"/>
</composite-id>
请注意,强烈建议将您的ID设置为一个单独的类('component'),它实现hashCode并且正确地等于,并且是Serializable。否则,您只能使用session.get()
或session.load()
查找对象的方式非常笨拙。
答案 1 :(得分:4)
也许实际上是这样的:
<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获得更好的结果。例如,在这种情况下,您没有自己的角色表;但是你似乎在描述的内容很自然地被建模为用户和角色类,它们之间存在多对多的关系。像这样:
<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_roles
的模式,现在user_roles
将在用户名和角色名称列中包含一个主键。您现在还可以在某处悬挂有关角色的其他信息,例如说明。
此外,您发布的错误是ClassNotFoundException,这似乎不太可能是您的映射的实际问题。
如果必须的话,你可以使用复合ID来做到这一点,但是我会说这是一个很痛苦的事情,你只是不想为这么简单的事情而努力。
答案 2 :(得分:4)
我添加了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 :(得分:2)
Sergio,看看这个composite key mapping in hibernate教程。可能会帮助你。