NHibernate Envers:使用继承保存修订时的问题

时间:2014-10-29 10:49:06

标签: nhibernate nhibernate-envers

考虑以下(伪代码)模型:

Job {id}

JobTranslation : Job {id}

JobResource {jobId, resourceId}

Resource  {id}

如果我在客户端应用程序中创建一个新的JobResource并保存它,Envers会在Job,Resource和JobResource的审计表中创建一条记录。 REVCHANGES中记录的实体类型是Job,Resource和JobResource。

现在,当我使用Envers API查询此修订时,它会尝试创建Job类型的实体,这会引发异常,因为它是一个抽象类,无法实例化。

我到目前为止找到的唯一解决方法是更改​​Job上的字段(例如updateDate)以强制Envers在JobTranslation审计表中创建修订。这样,在查询修订时,Envers会创建一个新的JobTranslation实例。

怎样才能更优雅地修复?在所有情况下,Envers是否有可能在JobTranslation审计表中创建记录?在我看来这很棘手,因为实际上还有其他类继承自Job。

编辑 - 映射:

BaseEntityMapping.cs

 public class BaseEntityMapping<T> : ClassMapping<T> where T : BaseEntity
 {
    public BaseEntityMapping()
    {
        this.Lazy(true);

        this.Id(x => x.Id, map =>
        {
            map.Generator(Generators.GuidComb);
            map.UnsavedValue(new Guid());
        });
 }

JobBaseMapping.cs

public class JobBaseMapping : BaseEntityMapping<Job>
{
    public JobBaseMapping()
    {
        this.Property(x => x.Deadline, map => map.NotNullable(true));
     }
}

JobTranslationMapping.cs

public class JobTranslationMapping : JoinedSubclassMapping<JobTranslation>
{
    public JobTranslationMapping()
    {
        this.Key(x =>
        {
            x.Column("Id");
        });
        this.Property(x => x.PriorityId, map =>
        {
            map.Column("PriorityId");
            map.Insert(false);
            map.Update(false);
            map.NotNullable(true);
        });
 }

JobResourceMapping.cs

public class JobResourceMapping : BaseEntityMapping<JobResource>
{
    public JobResourceMapping()
    {
        this.Property(x => x.JobId, map =>
        {
            map.Column("JobId");
            map.Insert(false);
            map.Update(false);
        });

        this.ManyToOne<Job>(x => x.Job, map =>
        {
            map.Column("JobId");
            map.Cascade(Cascade.None);
            map.NotNullable(true);
        });

        this.Property(x => x.ResourceId, map =>
        {
            map.Column("ResourceId");
            map.Insert(false);
            map.Update(false);
        });

        this.ManyToOne<Resource>(x => x.Resource, map =>
        {
            map.Column("ResourceId");
            map.Cascade(Cascade.None);
            map.NotNullable(true);
        });
    }
}

资源

 public class ResourceMapping : BaseEntityMapping<Resource>
 {
    public ResourceMapping()
    {
        this.Property(x => x.ResourceType);
    }
 }

编辑2

envers查询查询根据某些条件过滤的一些JobResource(此处未说明)

        revisionsOfEntity = revisionsOfEntity.Cast<IList>().Where(x => ((JobResource)((object[])x)[0]).Job.SourceMaterial.RequestId == requestId).ToList();

其中object []是ForRevisionsOfEntity返回的3元素数组。

只要JobTranslation表中存在记录,此查询就可以正常工作。否则,在调用.Job.SourceMaterial时会出现异常,因为无法创建作业。

0 个答案:

没有答案