Trace an Entity to get all modified column name and value - java

I am using Envers to audit data in my project.
Now I need to show all modified columns and their values to user.
But I am not able to get any query which can traverse an Entity to get all modified columns of that particular entity.
I found that link, but this is not solution of my problem, I can not give all column name with "hasChanged()" as their is much columns in each Entity.

We have already planned to introduce a much more efficient approach for users as a part of the next major Hibernate release. You can find details about it here, HHH-8058.

Related

Add Column to Cassandra db with out losing data

I am using Cassandra database integrated into a spring boot application.
My Question is around the schema actions. If I need to make structural changes to the DB, say add a column to a table, the database needs to be recreated, however this means all the existing data gets deleted:
schema-action: CREATE_IF_NOT_EXISTS
The only way I have managed to solve this is by using the RECREATE scheme action, but as mentioned earlier, this results in data-loss.
What would be the best approach to handle this? To add structural changes such as a column name with out having to recreate the database and lose all existing data?
Thanks
Cassandra does allow you to modify the schema of an existing table without recreating it from scratch, using the ALTER TABLE statement via cqlsh. However, as explained in that link, there are some important limitations on the kind of changes you can do. You cannot modify the primary key of the table at all, you can add or delete regular columns, and you can't change the type of a column to a non-compatible one.
The reason for most of these limitations is how Cassandra needs to deal with the old data that already exists in the table. For example, it doesn't make sense to say that a column A that until now contained strings - will now contain integers - how are we supposed to handle all the old values in column A which weren't integers?
As Aaron rightly said in a comment, it is unlikely you'll want to do these schema changes as part of your application. These are usually rare operations which are done manually, or via some management application - not your usual application.

Is there a way to uniquely identify a column via jdbc? I do not mean via schema table column

I am trying to track changes made to a database (schema) using a java app. We are trying to track changes for each column/unique-constraint/index and table.
Functionally I know table.column is unique. So, if the datatype of a column changes, we know which column to find and record the change. But what if the name changes? If JDBC's result set is ordered (it asks for index), then I can rely on the order to give me the same column everytime, even if the name changes. Will there be any surprises here, since it is a result 'set'?
However, I learnt that we can change the order of the columns as well. Isn't there any unique ID associated with the columns so that they can be picked up on that basis?
I would mostly not want to use information_schema route, but even though i checked there for mysql, found nothing useful.

Audit Using Hibernate Envers

I am using hibernate envers for making history of my data, it's working fine as well. The problem here is, it's creating duplicate data in history table i.e. creating data in history table whether there is any change in audited table or not. I want only changed fields stored in my history table. I am new to hibernate envers. What can I do?
If I understand your question correctly, Envers doesn't work that way, at least not out of the box.
Envers is a commit-snapshot auditing solution where just before commit, it examines audited entity state and determines whether any attributes have been modified or not and records a snapshot of all audited fields of that entity at that point in time. This means that the only time an audit entry isn't created is when no attributes have been modified.
But it also uses the snapshot approach because it fits really well with the Query API.
Consider the inefficiency that would occur if a query to find an entity at a given revision had to read all rows from that revision back to the beginning of time, iterating each row and merging the column state captured to just instantiate a single row result-set.
With the snapshot approach, it boils down to the following query, no loops or iterative work.
SELECT e FROM AuditedEntity e WHERE e.revisionNumber = :revisionNumber
This is far more efficient from a I/O perspective both with the database reading the data pages and the network for streaming a single row result-set rather than multi-row result-set to the client.
I'd say in this case, the saying "space is cheap" really holds true when you compare that against the cost and inefficiencies your application would face doing it any other way.
If this is something you'd like Envers to support, perhaps via some user configured strategy then you're welcomed to log a new feature request in JIRA for hibernate-envers and I can take a look at its feasibility.
I had similar problem.
In my case the error was that audited field had higher precision than the database field. Please see my reply to another thread: https://stackoverflow.com/a/65844949/13381019

Using a selective #Entity

I have searched StackOverflow for some time now, but have not been successful so far.
Thus creating this Question...
I am currently using JPA, but I have come across a problem (at least, for me it is). Here is the situation:
I have created a system in which a user can be removed, though not removed from the database (for the sake of holding on to the orders of this particular user). For this to work, I have simply added a boolean to the Entity User. All good so far, but here comes the tricky part. As the usage of the system does not require any 'removed' users, I do not want to retreive them from the Database.
Is there any way to add a statement of some kind to the #Entity annotation? Or shouldn't I be using #Entity at all, in this case?
Thanks in advance for the help!
PS. I am not looking for a solution in which I would have to create an User_OLD table of some kind.
First, I suggest renaming column "removed" to "inactive", because you do not remove user.
For retrieving entities, there are two choices here:
Create USER_ACTIVE VIEW in database based on inactive == false and
change your #Entity to use USER_ACTIVE view.
Add WHERE inactive == false clause on retrieval from USER table.
If you have Entity, which holds Collection of Users, which is annotated with #FetchType.LAZY:
Fetch users when needed with the same where clause as defined above.

In Hibernate Envers is it possible to query ALL entities for a given revision?

I'm looking at Hibernate Envers to solve two problems for me. First is auditing, fine. Second is the ability to roll-back a change made in a revision. This will be implemented by
Finding all the entities modified in a revision
Finding the corresponding previous version of each entity
Creating new versions that effectively reverse the changes made (new->delete,delete->new,update->update)
Commit new objects
However I can't see a way of querying the list of entities for a particular revision. There's a method that does it at a class level but not a global level. Is this possible?
What does it mean to query list? Query table -
http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/envers/query/AuditQueryCreator.html#forEntitiesAtRevision(java.lang.Class, java.lang.Number)
forEntitiesAtRevision(java.lang.Class, java.lang.Number)
Query list - implement filtering in java code.
Revision number is a transaction number. It is not a version of an entity number. It is a number representing version of an entity in transaction.
If you need to find list of entities revision than you can iterate over list of entities and find Revision of each from the list by query forEntitiesAtRevision(java.lang.Class, java.lang.Number)

Categories