场景:file和attachment是多对多的关系,存在一张关联表file和attachment的关联表。
一个file有多个attachment,在file的实体类中应该有一个list保存该file的所有attachment。
如下:
private IList<RsAttachment> _attachments = new List<RsAttachment>();
public virtual IList<RsAttachment> Attachments
{
get { return _attachments; }
set { _attachments = value; }
}
映射文件部分如下:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="RimaSoftApplication.Domain" assembly="RimaSoftApplication.Domain">
<class name="RimaSoftApplication.Domain.RsFiles" table="T_Files" lazy="false">
<id name="ID" column="FileID">
<generator class="native" />
</id>
<property name="PublicFileBoxID" column="PublicFileBoxID" />
<property name="PrivateFileBoxID" column="PrivateFileBoxID" />
<property name="KeyWords" column="KeyWords" />
<property name="FileTitle" column="FileTitle" />
<property name="FileContent" column="FileContent" />
<property name="CreateTime" column="CreateTime" />
<property name="Readers" column="Readers" />
<property name="Remark" column="Remark" />
<many-to-one name="CreateUser" column="CreateUserID" class="RsUser" />
<!--<many-to-one name="PrivateFileBox" column="FileBoxID" class="RsPrivateFileBox" />
<many-to-one name="PublicFileBox" column="FileBoxID" class="RsPublicFileBox" />-->
<bag name="Attachments" table="T_Files_Attachment" lazy="true">
<key column="FileID"/>
<many-to-many class="RimaSoftApplication.Domain.RsAttachment" column="AttachmentID"/>
</bag>
</class>
</hibernate-mapping>
当需要复制一份文件时,需要同时复制它所有的attachment,如果这样拷贝:
public CopyOrCutFileResponse CopyFile(CopyFileRequest request)
{
CopyOrCutFileResponse response = new CopyOrCutFileResponse();
if (request != null)
{
RsFiles rsFile = _filesDao.GetById(request.ID);
RsFiles rsFileNew = new RsFiles();
// 对新文件进行赋值
rsFileNew.CreateTime = rsFile.CreateTime;
rsFileNew.CreateUser = rsFile.CreateUser;
rsFileNew.FileContent = rsFile.FileContent;
rsFileNew.FileTitle = rsFile.FileTitle;
rsFileNew.KeyWords = rsFile.KeyWords;
rsFileNew.PrivateFileBoxID = request.destFileBoxID; //所属PrivateFileBox的ID
rsFileNew.Readers = rsFile.Readers;
rsFileNew.Remark = rsFile.Remark;
rsFileNew.Attachments = rsFile.Attachments;
_filesDao.Add(rsFileNew);
response.OPResult = SysEnum.OperationResult.OR_SUCCEESS;
}
return response;
}
则会出现题目中的错误,因为这两个对象引用的list是同一个list,这在hibernate中是不允许的,参见Hibernate reference第6章的"Two entities may not share a reference to the same collection instance"。
这种问题常见于复制对象时。
正确的复制应该如下所示:传值而不是传递引用!!
public CopyOrCutFileResponse CopyFile(CopyFileRequest request)
{
CopyOrCutFileResponse response = new CopyOrCutFileResponse();
if (request != null)
{
RsFiles rsFile = _filesDao.GetById(request.ID);
RsFiles rsFileNew = new RsFiles();
// 对新文件进行赋值
rsFileNew.CreateTime = rsFile.CreateTime;
rsFileNew.CreateUser = rsFile.CreateUser;
rsFileNew.FileContent = rsFile.FileContent;
rsFileNew.FileTitle = rsFile.FileTitle;
rsFileNew.KeyWords = rsFile.KeyWords;
rsFileNew.PrivateFileBoxID = request.destFileBoxID; //所属PrivateFileBox的ID
rsFileNew.Readers = rsFile.Readers;
rsFileNew.Remark = rsFile.Remark;
foreach (RsAttachment item in rsFile.Attachments)
{
rsFileNew.Attachments.Add(item);
}
_filesDao.Add(rsFileNew);
response.OPResult = SysEnum.OperationResult.OR_SUCCEESS;
}
return response;
}