考虑以下(伪代码)模型:
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时会出现异常,因为无法创建作业。