NHibernate Envers: Cannot insert duplicate key into object

I use Envers to audit tables, but it creates some audit tables for unknown / missing tables. It looks like a many-to-many relationship audit table for a many-to-one relationship.

Is it correct? If so, why?

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

But when I try to delete / delete and HorarioFixo, I get an error.

The error I am getting is:

 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. 

This is duplicated by 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 

All of this is part of the code. If you need anything else, leave a comment.

My classes:

 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; } } 

My mappings:

 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 and Envers configurations:

 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); } } 
+6
source share
2 answers

If you use a one-to-many one-way, Envers needs a reference table in order to have the correct history.

If you are using bidirectional one-to-many links table is not required.

See the answer .

+1
source

I just changed my class to

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

And added the JanelaHorarioFixo property to identify the type. But the dbo.HorarioFixo_JanelaHorarioFixo_Auditoria table still exists, and I don't know why.

+4
source

All Articles