That explains your problems. If you choose FluentConfiguration, envers' attributes aren't used/read at all. You cannot mix configuration by code (FluentConfiguration) and attribute configuration (AttributeConfiguration). In other words - the attributes you set on your CustomRevInfo isn't read/used in your case.
In (Hibernate) Envers only attribute configuration is supported. These options have been ported as AttributeConfiguration. Most of the configuration options is in NHibernate Envers also available in FluentConfiguration but probably some are still not ported. I'm not using "tracking entity names" myself and I currently don't have the source code available, but you are probably right if you've found that some configuration options are missing there. If you find some configuration options not available in FluentConfiguration (which, by the way, I definatly prefer myself as well), please JIRA this. /Roger ________________________________________ Från: [email protected] [[email protected]] för Guilherme Paschoal [[email protected]] Skickat: den 20 februari 2014 17:59 Till: [email protected] Ämne: Re: [nhusers] [Envers] Query from different catalog Nope I'm not. The thing is, I have 139 classes in my Domain, I don't think that going into each of them and putting the [Audited] attribute (and dependence as well) on each one of them is the best option for my scenario right now. Actually, I didn't know about the AttributeConfiguration but I think that the FluentConfiguration is the option I should choose anyway. I took the approach of adding attributes to my CustomRevInfo class because It's was the only way I found to use Modified Entities Tracking and a RevisionListener (Not to mention that I am experimenting around envers configurations because my scenarion is pretty different/wrong from what envers was built to do). Why do I say that? Because there's no signature in "SetRevisionEntity" method that allows me to set the Id, Timestamp, Modified Entities and Listener all together. Am I wrong? On Thursday, February 20, 2014 12:56:47 PM UTC-3, Roger wrote: I've seen you're using attributes for your configuration. Are you sure you pass in an AttributeConfiguration (no FluentConfiguration) object to your nhConf.IntegrateWithEnvers method? From: [email protected]<javascript:> [mailto:[email protected]<javascript:>] On Behalf Of Guilherme Paschoal Sent: den 20 februari 2014 16:07 To: [email protected]<javascript:> Subject: Re: [nhusers] [Envers] Query from different catalog Roger, the "problem" is at the method private IEnumerable<System.Type> nhMappedTypesWithRevisionEntityAttribute(Cfg.Configuration cfg) { var ret = new HashSet<System.Type>(); foreach (var persistentClass in cfg.ClassMappings) { if (_metaDataStore.ClassMeta<RevisionEntityAttribute>(persistentClass.MappedClass) != null) ret.Add(persistentClass.MappedClass); } return ret; } Even though my CustomRevInfo class is decorated with the [RevisionEntity(typeof(CustomEntityTrackingRevisionListener))] attribute, the _metaDataStore.ClassMeta<RevisionEntityAttribute>(persistentClass.MappedClass) won't find it. There's no entry for the CustomRevInfo class in the _metaDataStore classmeta list. Just for checking, I configured CustomRevInfo to be audited and it appears on that same list. On Thursday, February 20, 2014 11:29:06 AM UTC-3, Roger wrote: I see that you use Set<string> for ModifiedEntityNames property. That should result in an exception (should be ISet<string>). This is probably an indication that something else is wrong. Have you mapped your revision entity (CustomRevInfo in your case)? You can look at the available green tests for tracking modified entities in Envers repo and see what the difference to your code is. https://bitbucket.org/RogerKratz/nhibernate.envers/src/d07de59913629dc77f7923e2fc3fac1df21a7f3f/Src/NHibernate.Envers.Tests/Integration/RevEntity/TrackModifiedEntities/?at=default From: [email protected] [mailto:[email protected]] On Behalf Of Guilherme Paschoal Sent: den 20 februari 2014 14:50 To: [email protected] Subject: Re: [nhusers] [Envers] Query from different catalog Roger, thanks for the answer. I tryed to implement the IEntityTrackingRevisionListener as you recommended but unfortunately, the Listener isn't called. One thing I noticed, is that even though I decorated the property ModifiedEntityNames with the [ModifiedEntityNames] attribute like it is said in the docs, the only way to get the Entity Changed Tracking to work is by setting: cfg.SetEnversProperty(ConfigurationKey.TrackEntitiesChangedInRevision, true); and this seems to ignore the custom class that I implement. Any thoughts? This is the code: [RevisionEntity(typeof(CustomEntityTrackingRevisionListener))] public class CustomRevInfo { [RevisionNumber] public virtual int Id { get; set; } [RevisionTimestamp] public virtual DateTime RevisionDate { get; set; } public virtual string Usuario { get; set; } [ModifiedEntityNames] public virtual Set<string> ModifiedEntityNames { get; protected set; } public virtual void AddModifiedEntityType(string entityName) { ModifiedEntityNames.Add(entityName); } public virtual void RemoveModifiedEntityType(string entityName) { ModifiedEntityNames.Remove(entityName); } public override bool Equals(object obj) { if (this == obj) return true; var casted = obj as CustomRevInfo; if (casted == null) return false; if (Id != casted.Id) return false; if (RevisionDate != casted.RevisionDate) return false; if (Usuario != casted.Usuario) return false; if (!ModifiedEntityNames.Equals(casted.ModifiedEntityNames)) return false; return true; } public override int GetHashCode() { var result = Id; result = 31 * result + (int)(((ulong)RevisionDate.Ticks) ^ (((ulong)RevisionDate.Ticks) >> 32)); return result; } } public class CustomEntityTrackingRevisionListener : IEntityTrackingRevisionListener { public void NewRevision(object revisionEntity) { var usuario = Thread.CurrentPrincipal.Identity.Name<http://Thread.CurrentPrincipal.Identity.Name>; ((CustomRevInfo)revisionEntity).Usuario = usuario; } public void EntityChanged(Type entityClass, string entityName, object entityId, RevisionType revisionType, object revisionEntity) { ((CustomRevInfo)revisionEntity).AddModifiedEntityType(entityClass.FullName); } } On Thursday, February 20, 2014 5:44:51 AM UTC-3, Roger wrote: Glad things start to work for you. About your listener issue... Have a look at IEntityTrackingRevisionListener here; http://envers.bitbucket.org/#envers-tracking-modified-entities-revchanges Will fix the typo in the docs. Thanks! From: [email protected] [mailto:[email protected]] On Behalf Of Guilherme Paschoal Sent: den 19 februari 2014 21:44 To: [email protected] Subject: Re: [nhusers] [Envers] Query from different catalog Finally, I made session.Auditer().CrossTypeRevisionChangesReader().FindEntities(3) work! What I had to do is, instead of extending DefaultTrackingModifiedEntitiesRevisionEntity, I annotated the class and the necessary fields. And I don't know if it is important but I reviewed Equals()' code and copied the GetHashCode content from the DefaultTrackingModifiedEntitiesRevisionEntity implementation. Like this: ps: Unfortunately, the Listener isn't being called. [RevisionEntity(typeof(RevInfoListener))] public class CustomRevInfo { [RevisionNumber] public virtual int Id { get; set; } [RevisionTimestamp] public virtual DateTime RevisionDate { get; set; } public virtual string Usuario { get; set; } [ModifiedEntityNames] public virtual Set<string> ModifiedEntityNames { get; protected set; } public override bool Equals(object obj) { if (this == obj) return true; var casted = obj as CustomRevInfo; if (casted == null) return false; if (Id != casted.Id) return false; if (RevisionDate != casted.RevisionDate) return false; if (Usuario != casted.Usuario) return false; if (!ModifiedEntityNames.Equals(casted.ModifiedEntityNames)) return false; return true; } public override int GetHashCode() { var result = Id; result = 31 * result + (int)(((ulong)RevisionDate.Ticks) ^ (((ulong)RevisionDate.Ticks) >> 32)); return result; } } Oh, btw, the docs says that the attribute's name is ModifiedEntityTypes when in fact it is ModifiedEntityNames. On Wednesday, February 19, 2014 4:06:40 PM UTC-3, Guilherme Paschoal wrote: Just to keep the update on my progress coming: I found out that the "query did not return unique result" exception is thrown by the criteria API's "query.UniqueResult" executed in FindEntityTypes method. I debugged it and changed it for "query.List()" and it executed the query yet it returned something like this: [0] {NHibernate.Envers.DefaultTrackingModifiedEntitiesRevisionEntity} object {DefaultTrackingModifiedEntitiesRevisionEntityProxy} [1] {NHibernate.Envers.DefaultTrackingModifiedEntitiesRevisionEntity} object {DefaultTrackingModifiedEntitiesRevisionEntityProxy} [2] {MyNamespace.DataAccess.Audit.REVINFO} object {MyNamespace.DataAccess.Audit.REVINFO} the two first rows in the result, seem to be related to the fact that 2 entities are modified on the revision. I'll keep looking into it. On Wednesday, February 19, 2014 6:00:18 AM UTC-3, Roger wrote: Can't see anything wrong on what you've posted. If you don't have the time to isolate your problem a bit more, I don't know I'm afraid. Sorry. You might want to take a look at Envers' tests and see what differs to try to find out why they work but you have problems in your environment. If you do find the time to isolate your problem and it turns out it's really a bug in Envers, please report it to the JIRA. Good luck! /Roger From: [email protected] [mailto:[email protected]] On Behalf Of Guilherme Paschoal Sent: den 18 februari 2014 18:38 To: [email protected] Subject: Re: [nhusers] [Envers] Query from different catalog Roger, Actually, I have to say I'm sorry first, I was only testing GetCurrentRevision... Other querys "work". * session.Auditer().GetCurrentRevision(false) returns Id = 0 and date = now; * session.Auditer().CrossTypeRevisionChangesReader().FindEntities(3,RevisionType.Modified) returns "query did not return a unique result: 3". Actually there are 2 records for revision 3 in RevChanges table. How should I execute this query? I'm doing it like it is said in the docs. * session.Auditer().GetRevisionNumberForDate(new DateTime(2014, 02, 17,15,55,03,503,DateTimeKind.Local)) returns "query did not return a unique result: 2". There's only one record in Revinfo for this exact datetime. * session.Auditer().GetRevisions(typeof (ItemDeConfiguracao), 1) returns 6 records (it looks like its something with it's query's inner/left join): * Name - Value * [0] - 1 * [1] - 3 * [2] - 4 * [3] - 1 * [4] - 3 * [5] - 4 This is my nhibernate session factory: public static ISessionFactory SessionFactory { get { try { if (_sessionFactory == null) { lock (SyncRoot) { _sessionFactory = Fluently.Configure() .Database(MsSqlConfiguration.MsSql2008.Dialect<CustomMsSql2008Dialect>() //.ConnectionString(c => c.FromConnectionStringWithKey("DBSQL_AUDIT")).ShowSql()) .ConnectionString(c => c.FromConnectionStringWithKey("DBSQL")).ShowSql()) .Mappings(m => m.FluentMappings.AddFromAssemblyOf<NHibernateHelper>()) .ExposeConfiguration(ConfigurarEnvers) //.ExposeConfiguration(c => new SchemaExport(c).SetOutputFile(@"C:\Temp\scripteste.txt").Execute(true, true, false)) .BuildSessionFactory(); } } return _sessionFactory; } catch (FluentConfigurationException ex) { // Log.Fatal(ex); throw new Exception("Não foi possível conectar-se ao banco de dados. Favor entrar em contato com o administrador do sistema.", ex); } } } private static void ConfigurarEnvers(Configuration cfg) { var enversConf = new NHibernate.Envers.Configuration.Fluent.FluentConfiguration(); var rev = new RevInfoListener(); enversConf.Audit(Dominio.Classes.Helper.ObterSubClassesDeEntidadeBase()); cfg.SetEnversProperty(ConfigurationKey.TrackEntitiesChangedInRevision, true); cfg.SetEnversProperty(ConfigurationKey.DefaultSchema, "dbo"); cfg.SetEnversProperty(ConfigurationKey.DefaultCatalog, "DB_AUDIT"); cfg.IntegrateWithEnvers(enversConf); } And this is my Custom REVINFO class [RevisionEntity(typeof(RevInfoListener))] public class REVINFO : DefaultTrackingModifiedEntitiesRevisionEntity { public virtual string Usuario { get; set; } } RevInfoListener public class RevInfoListener : IRevisionListener { public void NewRevision(object revisionEntity) { var usuario = Thread.CurrentPrincipal.Identity.Name<http://Thread.CurrentPrincipal.Identity.Name>; ((REVINFO)revisionEntity).Usuario = usuario; } } And REVINFOMap. The value returned by configurationmanager.appsettings["BandoDeDadosAuditoria"] is "DB_AUDIT.dbo". It's the catalog and schema name. It's the way I found to force it uses the Audit database for querying, otherwise it will try to query from the Session's catalog. public class REVINFOMap : ClassMap<REVINFO> { public REVINFOMap() { var bdAudit = ConfigurationManager.AppSettings["BancoDeDadosAuditoria"]; Schema(bdAudit); Table("REVINFO"); Id(x => x.Id, "REV").GeneratedBy.Identity(); Map(x => x.RevisionDate, "REVTSTMP"); Map(x => x.Usuario, "Usuario"); } } Btw, The "Usuario" field is being inserted as NULL... It worked before I activated the TrackEntitiesChangedInRevision setting. And please don't ask me to post an Isolated Test or whatever... Our code is a total mess right now and for some freaking reason, an error is occurring when I try to open a session in test environment. We're on a total rush here. The company's president is on our asses these days. Yep, the president. thanks a lot in advance! On Tuesday, February 18, 2014 7:28:59 AM UTC-3, Roger wrote: AFAIK, that "should" work. Is it one specific query that doesn't work or is it all of them? How is your configuration object configured? From: [email protected] [mailto:[email protected]] On Behalf Of Guilherme Paschoal Sent: den 17 februari 2014 21:17 To: [email protected] Subject: [nhusers] [Envers] Query from different catalog Hello guys! I successfully got envers to work, saving to a different catalog. My problem is that unfortunately, querying from that catalog, won't work. It queries from the current session's catalog, not from the one I configured in "cfg.SetEnversProperty(ConfigurationKey.DefaultCatalog, "DB_AUDIT");". I've been searching around envers source but I couldn't find any tips on that. Anyone got that one working or has any tips for me? Thanks a lot in advance! -- You received this message because you are subscribed to the Google Groups "nhusers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/nhusers. For more options, visit https://groups.google.com/groups/opt_out. -- You received this message because you are subscribed to the Google Groups "nhusers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/nhusers. For more options, visit https://groups.google.com/groups/opt_out. -- You received this message because you are subscribed to the Google Groups "nhusers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]<javascript:>. To post to this group, send email to [email protected]<javascript:>. Visit this group at http://groups.google.com/group/nhusers. For more options, visit https://groups.google.com/groups/opt_out. -- You received this message because you are subscribed to the Google Groups "nhusers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/nhusers. For more options, visit https://groups.google.com/groups/opt_out. -- You received this message because you are subscribed to the Google Groups "nhusers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]<javascript:>. To post to this group, send email to [email protected]<javascript:>. Visit this group at http://groups.google.com/group/nhusers. For more options, visit https://groups.google.com/groups/opt_out. -- You received this message because you are subscribed to the Google Groups "nhusers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/nhusers. For more options, visit https://groups.google.com/groups/opt_out. -- You received this message because you are subscribed to the Google Groups "nhusers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/nhusers. For more options, visit https://groups.google.com/groups/opt_out.
