具有客户端生成ID的实体.我是否应该为NHibernate';s的ID

本文关键字:ID NHibernate 客户端 实体 是否 | 更新日期: 2023-09-27 18:20:33

我有一个类型为Video的对象。我将视频存储在我的数据库中,但我希望每个视频条目都是唯一的。唯一性由客户端提供的11位字符串决定。

因此,我生成了这个Video.hbm.xml文件:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Streamus" namespace="Streamus.Domain">
  <class name="Video" table="[Videos]" lazy="false" mutable="false">
    <id name="Id" length="11" type="String" />
    <property name="Title" not-null="true" />
    <property name="Duration" not-null="true" />
    <property name="Author" not-null="true" />
  </class>
</hibernate-mapping>

我无意删除或更新此表中的任何条目。所以,我把我的类标记为不可变的。

现在,我认为这是一个很好的方法,但我遇到了从父对象级联更新的问题。由于我的ID是在客户端生成的,并且我没有利用第二个标识符,NHibernate无法可靠地确定视频是否需要插入或更新(请注意,由于它是不可变的,因此永远不应该更新。)

类似于:

Video video = new Video("s91jgcmQoB0", "Tristam - Chairs", 219, "MeoMix");
new VideoManager().Save(video);
//  Create a new PlaylistItem and write it to the database.
string title = video.Title;
PlaylistItem playlistItem = new PlaylistItem(title, video);
Playlist.AddItem(playlistItem);
PlaylistManager.SavePlaylistItem(playlistItem);

其中PlaylistItem的hbm.xml将视频引用为:

<many-to-one name="Video" column="VideoId" not-null="true" cascade="save-update" />

上面的代码生成了一个NonUniqueObjectException。这是因为VideoManager在一个会话中处理视频,关闭它,然后PlaylistManager在新会话中重新引用相同的视频,但NHibernate无法适应,因为它没有好的ID。

删除cascade="保存更新"的选项可以解决这个问题,但我无法从NHibernate在数据库中隐式创建我的视频对象中获益。相反,我必须手动保存视频对象,然后再保存PlaylistItem对象。这显然并不理想。

所以,我想知道——我应该给我的视频对象分配一个GUID吗?如果是这样,我该如何强制执行这样一个事实,即我只希望在我的表中有唯一的视频条目,其中唯一性由11位字符串ID定义?

如果我能提供更多的信息,让我知道这一点。

具有客户端生成ID的实体.我是否应该为NHibernate';s的ID

首先修改video.hbm.xml中的ID部分,使其具有"指定"的生成器

<id name="id" ....>
    <generator class="assigned" />
</id>

这告诉nhibernate,您的ID是从客户端手动生成的。

同时,让同一个对象被多个会话操作会导致一致性错误。因此,要么为您的一批操作使用唯一的会话,要么通过使用会话确保在所有会话中正确跟踪您的对象。合并