How to add a "Viewed By" audit in Javers with using an explicit field on the entity being audited - javers

In our application, we have a requirement to audit "viewed by" events. Currently, we implemented this functionality by using an Audit table and manually logging it to the table during "GET" calls. I am trying to understand how to accomplish this in Javers.
In our current application, to find our changes, we use hibernate interceptor and manually add the changes to the audit table.
I thought that the easiest way to accomplish the "viewed" audit functionality in Javers is to add a "viewedBy" field to the entity being audited and manually update it in "GET" calls. But I am concerned about this approach as each time, there is a view, we are changing the version of the object(by physically updating it) and the state is being saved to the jv_snapshot table.
I expect that the viewed by audits will be part of javers.findChanges() method, so that the changes are tracked in a chronological order and also possibly be paginated.

Related

Hibernate envers + hibernate-search : Reading audit information over Lucene/Elasticsearhc indexes

I'm using hibernate-envers for audit purposes in an application. I'm also using hibernate-search in order to search/read the information of JPA entities in the application.
I was wondering if there's any kind of configuration/integration that can make hibernate-envers work with the audit enties/tables, over indexes too, in order to read with hibernate -search that information from the indexes.
I would like to avoid doing it "manually", for example, using envers event listeners in order to create/manipulate a new index manually for the audited entity, using a new JPA Entity modelling the Audit entity information including #Indexed annotation, fields etc.).
Ideally was wondering if there's support for envers/search integration out of the box, without custom development, to achieve storing all audit information in new _aud indexes.
Thanks in advance, any piece of advice is appreciated.
It's certainly not possible out of the box.
If it ever becomes possible, you won't benefit from all the Envers features such as "get me this entity at this revision". You will simply index all the revisions of each entity, and you will only be able to query (and retrieve) these revisions. That would be queries such as "get all revisions of the entity with id 1 where name contained "some text".
Also, this will not remove the need for audit tables. The indexes will exist in addition to the audit tables.
That being said, I just gave it a try and we could make it possible in Hibernate Search 6 with just a few changes. If you're still interested, you can have a look there: https://hibernate.atlassian.net/browse/HSEARCH-4238

Old value in _aud table in envers

I have integrated hibernate envers in spring boot. Now my requirement is to have old value also for the particular column when value changed in *_AUD tables. However I cant see any feature available in Hibernate Envers plugin.
Please suggest.
Thanks
Unfortunately what you are looking to do just isn't someting supported.
It's one thing to think of an entity and needing to store basic type values such as strings or numeric data and have its old/new value represented by two columns in the audit table; however when you move beyond basic entity mappings to ones where you have relationships between entity types or collections; you begin to see that trying to store old/new data in the same row just isn't efficient and in some cases feasible.
That said, you can still read the audit history and deduce these old/new values using a variety of ways that include the Envers Query API, Debezium, or even basic database triggers.

How to catch errors in Envers?

I have set my auto updating of tables to none
spring.jpa.properties.hibernate.hbm2ddl.auto=none
That way when I am running Envers I will have to create the audit tables on my own. However when I have set an entity to be audited with the #Audited annotation and I have not created an audit table for that entity I run into an error because Envers then tries to populate the audit table that does not exist. This error is crucial because it then breaks the process of updating/inserting/deleting the entity because of the audit breaking.
Is there any way to have some sort of try/catch for Envers such that if there is this sort of error it does not break the main process?
P.S.
I am also using a test database to create the audit tables automatically, but it runs at a set time or when called. I would still like some way to check for errors and in a way bypass the auditing if there is an error in case I forget to call the script or the test database updating of the tables fails.
This error is crucial because it then breaks the process of updating/inserting/deleting the entity because of the audit breaking.
That's kinda the point here.
When you define an entity mapped with #Audited you have specified that you want track changes to that entity and therefore if such changes cannot be tracked due to a missing table or column the transaction will be rolled back to maintain consistency state between the audit tables and the main entity table.
In Hibernate 6, the idea there is we're actually considering introducing categorized HBM2DDL control where you can set none for your main entity tables and use update for Envers, which completely avoids this problem you face entirely since the point behind Envers is to shadow the main tables.
For now you could simply set the hbm2ddl.auto configuration property to validate to at least report the problem earlier in your process rather than during runtime if a table is missing.

How to retrieve deleted record?

I wonder how to retrieve deleted record that audited with Javers, as I know how to retrieve version changelog but when the record deleted from database table, there is no ID to retrieve audit record.
There is no dedicated filter for selecting deleted objects snapshots.
You can use general purpose queries like byClass() and filter selected snapshots by SnapshotType on your own, although it will not be very efficient.
New SnapshotType filter can be easily implemented in JaVers JQL, consider contributing a PR.

Performance impact when creating Audit trail using trigger in MS SQL Server 2012

In SQL Server 2012 database we want to create audit trail for almost all major tables on Update and Delete operations.Noramally we creating Audit Trail using trigger on each table and store it on shadow table. So there is any performance impact? if huge records updated or deleted on any table. There is anyother way to implement Audit trail?
Typically, when I implement and audit trail for DB tables, I implement it via code, not in triggers. When implemented in code, you can provide additional context information, such as the reason the change was made, who made the change, what was the reason behind the change, etc., which is a very common business requirement. In a typical multi-layer application design, we have DAOs for each table and the business services which implement the updates are responsible for calling the separate DAOs for the core table update and the history entry insert. This approach is no good if you want a bunch of different sources directly making table updates to the DB, but it's a natural approach if you have a service-oriented architecture and your one set of services are the only way into and out of those tables.
If you implement audit trail using this approach, you of course need to make sure the audit trail record is inserted in the same transaction as the modification to the core table.
Whether this would perform better than a trigger-based approach, I couldn't say. My guess would be that if you are using bulk insert operations it may run faster, but would probably be slower in the more common scenario where you are updating/deleting one record at a time via SQL. It's another option you could explore, though.

Resources