尝试在User
和Role
之间实现相对简单的关系。 User
可以有多个角色,同一Role
可以属于任意数量的User
。 Role
是共享的,即所有 admin User
引用同一个类Role
的实例。
User
映射:
<class name="User" lazy="false" table="Users">
<id name="Id" type="int">
<generator class="native"/>
</id>
<property name="Name" column="Username" />
<bag name="RoleList" table="User_Role" inverse="true" lazy="false" cascade="save-update">
<key column="UserId" foreign-key="Id"/>
<many-to-many class="Role" column="RoleId"/>
</bag>
</class>
Role
映射:
<class name="Role" lazy="false" table="Roles">
<id name="Id" type="int">
<generator class="native"/>
</id>
<property name="Name" column="Rolename"/>
<property name="Description"/>
</class>
有三个数据库表:一个用于User
,一个用于Role
,第三个用于多对多关系(带有两个外键:UserId
和RoleId
)。主键是这两者的复合键。
有问题的场景:角色是预定义的。在我的C#代码中,我正在构建一个用户,同时将角色附加到它。该角色是使用正确的 id 从DB成功提取的对象。我正在尝试将用户保存在数据库中。
现在转到问题:我收到重复密钥数据库错误,因为NHibernate正在尝试将Role
对象插入到相应的表中。由于RoleId
已经属于现有的角色,我希望不会在数据库中插入新角色。
Gory详细信息:我也尝试调试NHibernate并看到由于某种原因EntityIdentityInsertAction
收到Role
并调用基础构造函数。在对基础构造函数的调用中,Id
参数是一个简单的硬编码 null 。堆栈跟踪还包含对SaveWithGeneratedId()
(链中较早的某个位置)的调用,这意味着由于某种原因,不会计算现有Id
对象的Role
。
这是迄今为止我成功找到的所有信息。请告诉我我做错了什么。
答案 0 :(得分:1)
我的第一个直觉反应是你不希望在用户的Roles集合上使用cascade =“save-update”。
如果您希望在保存用户时保存/更新实际角色所做的更改,则只需要这样做。
我认为你所追求的是确保关系保存,但无论你的级联设置如何,都会发生这种情况。