How to audit hibernate entity access - spring

I need to log not only modifications, but every access to Entity.
I've looked into EntityListeners and Envers but couldn't find anything usefull.

Related

Disable setting up Audit fields in create/update requests in Spring Data REST

I'm using combination of various Spring components - Boot (2.3), Data, Data REST, Springdoc. In my model objects I use auditing - I annotate some fields with #CreatedBy, #CreatedDate etc. I would like to disable possibility to set value of those audit fields through REST API. At the same time, I want this information to be available when retrieving data.
Seems like quite obvious thing to do, but I'm unable to find a way to do this. By default I can easily provide those values in API calls and see them persisted.
Ideally, such configuration change would be visible also in OpenAPI spec generated by Springdoc (in model of request).
So it turns out that I'm silly :)
So my error was that authentication and authorization was disabled at that time. Once enabled, I wasn't able to provide values for createdBy and other fields as they were just getting overridden with correct values.
When it comes to OpenAPI specification, I had to annotate fields with:
#Schema(accessMode = Schema.AccessMode.READ_ONLY)
from io.swagger.v3.oas.annotations.media.Schema;. This resulted in correct info. See Swagger view:
I guess the problem comes from your bad design. Please consider your design is correct or not. I guess in your design, besides Spring Data REST endpoints (APIs), there are other code which can create and update your object and save to database.
You question has nothing to do with Spring Data REST. Audit fields annotated with #Createdxx and #LastModifiedxx is auto updated by Spring Data repository, and Spring Data REST just calls the Spring Data repository to persist data.
Answer below two questions helps clarify your design.
Question 1:
If you want to keep create (POST) endpoints which are created by Spring Data REST by default, and you don't want audit fields annotated with #Createdxx to be set, then what code is responsible to set those audit fields?
Assume you send a POST request to create an object, do you want createdBy and createdDate to be null? Or would createdBy and createdDate be updated later by other code?
Question 2:
If you want to keep update (PUT/PATCH) endpoints which are created by Spring Data REST by default, and you don't want audit fields annotated with #LastModifiedxx to be updated, then what code is responsible to update those audit fields? And this also results in imcomplete audit (you make update, but lastModified info not updated).

Can anyone explain detailed use of persistent.xml file in hibernate JPA project?

I have read articles about hibernate -JPA on the internet but unable to understand how it used and how it is working in the background for hibernate. Also, need information about what should be the name of a persistent unit in persistent.xml and what is the use of it?
Mainly we use persistnce.xml / hibernate.cfg.xml to tell hibernate the following details
What Database you're using? so, that hibernate executes all the queries w.r.t that Database
Connecting to Database like Providing Username and password
The database name
Hibernate mapping files name and many more
Go through this link

Need CRUD operations for javers

I want to archive restore the javers audit records. So I want ability to delete the records and insert them again.
Does javers repository provide delete/insert API or we use standard JPA techniques to do that ?
I have searched through the API. It has some hallowDelete API which may not serve purpose as of now.
I should have API like javers.deletebyCommitId(Long id) and javers.insertAuditData(javersEntity) etc.
I think you need to konw some data operation framework, like mybatis and hibernate, maybe jpa is more suitaable you.
I suggest you to use mybatis + mapper. they have own quick start, i think that may help you.
mybatis: https://github.com/mybatis/mybatis-3
Mapper: https://github.com/abel533/Mapper

Javers - What are advantages of using Javers instead of Envers?

I am developing a RESTful API using Spring Data REST. Now for auditing, Spring does have the option to auditing meta data like created_date and modified_date but they don't provide entity versioning.
Currently there are two popular libraries for entity version which are Envers and Javers. I have looked over for a comparison of both but there arent any articles on this matter.
So what are the benefits and drawbacks of using Javers over Envers?
There are two big difference between JaVers and Envers:
Envers is the Hibernate plugin.
It has good integration with Hibernate but you can use it only with traditional SQL databases.
If you choosed NoSQL database or SQL but with other persistence framework like
JOOQ — Envers is not an option.
On the contrary, JaVers can be used with any kind of database and any kind of
persistence framework. For now, JaVers comes with repository implementations for MongoDB and
popular SQL databases. Other databases (like Cassandra, Elastic) might be added in the future.
Envers’ audit data model is a copy of application’s data model. As the doc says:
For each audited entity, an audit table is created.
By default, the audit table name is created by adding a _AUD suffix to the original name.
It can be advantage, you have audit data close to your live data. Envers’ tables look familiar.
It’s easy to query them with SQL.
JaVers uses its own Snapshot model for audit data.
Snapshots are decoupled from live data,
JaVers saves them to the single table (jv_snapshots) as JSON documents with unified structure.
Advantages? You can choose where to store audit data.
By default JaVers uses the same database as application does,
but you can point another database. For example, SQL for application and MongoDB for JaVers
or centralized JaVers database shared for all applications in your company).
Read this blogpost with full JaVers vs Envers comparison:
https://javers.org/blog/2017/12/javers-vs-envers-comparision.html
Enver is like git for a database.
I do not know Javers but a complete Envers databinding has this advantages:
A table is created in the database called REVINFO having a timestamp and a PK.
To every entity that is audited, one shadow-copy is created. Theese shadow-copies have every field nullable and the PK is not a PK. Theese shadow-copies have a new field, the reference to the table REVINFO.
This gives Enver the possibility to record changes that has been made in the past in this shadow-copies. You can move that shadow-tables into an different database.

Best way for Audit in Spring

I am creating an application where users can create games. I am storing in the entity Game who was the user that created the game, I mean, the owner of the game. The entity Game has some relationships ONE_TO_ONE (RuleGame) and ONE_TO_MANY (PublicZone and PrivateZones) to other entities.
What I want is that only the owner of the game and users with ROLE_ADMIN and ROLE_STAFF be able to edit the game and its relationships.
Another way to say this, think like a Social Network, just me and the ADMIN can edit my profile but I cannot edit the profile of other users.
Of course I can create my own logic in a #Service and in each "update" method of the controller of those entities (Game, PublicZone and PrivateZones) call it and check this but I am wondering is there is a better way to go.
I was reading about Audit, like Hibernate Envers, but it is for wiki-like software, log who added/updated/deleted, so it doesnt fit in what I need.
I am using Spring 4.1.6, Spring Data Jpa 1.8.0, Spring Security 4 and Hibernate 4.3.8
Every suggestion is welcome!
You will want to use spring-data-jpa auditing along with a security framework such as spring security. This will allow the username to be added automatically when a record is created and modified with no extra logic from yourself.

Resources