NHibernate Envers:不能在对象中插入重复键

本文关键字:插入 对象 Envers 不能 NHibernate | 更新日期: 2023-09-27 17:53:45

我正在使用Envers审计表,但是它正在为未知/缺席的表创建一些审计表。它看起来像是多对一关系的多对多关系审计表。

这样对吗?如果是,为什么?

dbo.HorarioFixo - OK
dbo.HorarioFixo_Auditoria - OK
dbo.HorarioFixo_JanelaHorarioFixo_Auditoria - NOK
dbo.JanelaHorarioFixo - OK
dbo.JanelaHorarioFixo_Auditoria - OK

但是当我试图删除/删除和HorarioFixo时,我得到一个错误。

我得到的错误:

NHibernate.Exceptions.GenericADOException
could not execute batch command.[SQL: SQL not available]
   em NHibernate.Engine.ActionQueue.BeforeTransactionCompletionProcessQueue.BeforeTransactionCompletion()
   em NHibernate.Impl.SessionImpl.BeforeTransactionCompletion(ITransaction tx)
   em NHibernate.Transaction.AdoTransaction.Commit()
   em Foo.Testes.Servicos.TesteCanalDeTransmissaoService.RemoveDependenciasCorretamente() na TesteCanalDeTransmissaoService.cs: line 195
System.Data.SqlClient.SqlException
Violation of PRIMARY KEY constraint 'PK__HorarioF__450088476960C81E'. Cannot insert duplicate key in object 'dbo.HorarioFixo_JanelaHorarioFixo_Auditoria'.
Violation of PRIMARY KEY constraint 'PK__HorarioF__450088476960C81E'. Cannot insert duplicate key in object 'dbo.HorarioFixo_JanelaHorarioFixo_Auditoria'.
The statement has been terminated.
The statement has been terminated.

这是重复的SQL:

exec sp_executesql N'INSERT INTO HorarioFixo_JanelaHorarioFixo_Auditoria (REVTYPE, REV, HorarioFixoId, JanelaHorarioFixoId) VALUES (@p0, @p1, @p2, @p3)',N'@p0 tinyint,@p1 int,@p2 bigint,@p3 bigint',@p0=2,@p1=3,@p2=1,@p3=2 go

所有这些都是代码的一部分。如果你需要更多的东西,请留下评论。

我的类:

public class Entidade
{
    protected Entidade();
    public virtual long Id { get; set; }
    public virtual long Version { get; set; }
    public abstract override bool Equals(object obj);
    public override int GetHashCode();
}
public class Horario : Entidade
{
    protected Horario()
    {
    }
}
public class HorarioFixo : Horario
{
    public virtual int Frequencia { get; set; }
    public virtual ICollection<JanelaHorarioFixo> JanelasRemessa { get; set; }
    public virtual ICollection<JanelaHorarioFixo> JanelasRetorno { get; set; }
}
public class JanelaHorarioFixo : Entidade
{
    public virtual TimeSpan HorarioInicio { get; set; }
    public virtual TimeSpan? HorarioLimite { get; set; }
}

我的映射:

public class HorarioMap : ClassMapping<Horario>
{
    public HorarioMap()
    {
        Id(x => x.Id, mapper =>
        {
            mapper.Generator(Generators.Identity);
            mapper.UnsavedValue(0);
        });
    }
}
public class HorarioFixoMap : JoinedSubclassMapping<HorarioFixo>
{
    public HorarioFixoMap()
    {
        Property(x => x.Frequencia);
        Bag(x => x.JanelasRemessa, m =>
        {
            m.Cascade(Cascade.All);
            m.Lazy(CollectionLazy.NoLazy);
        }, map => map.OneToMany());
        Bag(x => x.JanelasRetorno, m =>
        {
            m.Cascade(Cascade.All);
            m.Lazy(CollectionLazy.NoLazy);
        }, map => map.OneToMany());
    }
}
public class JanelaHorarioFixoMap : ClassMapping<JanelaHorarioFixo>
{
    public JanelaHorarioFixoMap()
    {
        Id(x => x.Id, mapper =>
        {
            mapper.Generator(Generators.Identity);
            mapper.UnsavedValue(0);
        });
        Property(x => x.HorarioInicio, m => m.NotNullable(true));
        Property(x => x.HorarioLimite, m => m.NotNullable(false));
    }
}

NH和Envers配置:

var ormHelper = ORMHelperUtils.GetORMHelper();
var mapper = new MyConventionModelMapper();
_config = new Configuration();
mapper.AddMappings(ormHelper.GetMappings());
mapper.AddMapping(typeof(REVINFOMap));
ormHelper.SetupApplicationNeeds(_config);
_config.AddMapping(mapper.CompileMappingForAllExplicitlyAddedEntities());
_config.SetProperty(Environment.CurrentSessionContextClass, "call");
if (ormHelper.UseEnvers)
{
    var classesDominio = ormHelper.GetDomainTables();
    if (classesDominio.Any())
    {
        var envers = new FluentConfiguration();
        envers.Audit(classesDominio);
        envers.SetRevisionEntity<REVINFO>(e => e.Id, e => e.Date, new CustomRevisionListener());
        _config.SetEnversProperty(ConfigurationKey.AuditTableSuffix, "_Auditoria");
        _config.IntegrateWithEnvers(envers);
    }
}

NHibernate Envers:不能在对象中插入重复键

我刚把我的class改成

public class HorarioFixo : Horario
{
    public virtual int Frequencia { get; set; }
    public virtual ICollection<JanelaHorarioFixo> Janelas { get; set; }
}

并向JanelaHorarioFixo添加了一个属性来标识类型。但是桌子变了。HorarioFixo_JanelaHorarioFixo_Auditoria仍然在那里,我不知道为什么。

如果您使用单向一对多,Envers需要一个链接表才能拥有正确的历史记录。

如果使用双向一对多,则不需要链接表。