How to get all data in Audited table with hibernate envers? - java

I have a project where i have all my entities. And I have another project where I try to get all the data of each Audited table of each given Entity.
With Hibernate envers i know how to retrieve an object in a previous version.
AuditReaderFactory.get(Session sess) and Object AuditReader.find(Class<T> cls, Object primaryKey, Number revision)
But I don't know how to get All records data in an audited X with the rev et typerev field too.
Any idea?

Because i want to get a lot of data from an audited table (in some table i find the millions of revisions so to get that they take a lot of time whitch cause a timout for the server , specialy when i use hibernate envers , that why i change to native query and i found a lot of possibilities and fonctionalities in.

Related

Retrieve table hierarchie from Hibernate

Now and then I come into the situation that I have to display the table hierarchie of a database for further operations, currently in a data migration project where I have to treat "leaf tables" (tables which are leafes in the table dependency tree) in a different way.
I've always wanted to use Hibernate's meta information to retrieve and display the table dependency tree, but never knew how to approach the problem.
So can anyone give me feedback on whether Hibernate provides an API to do this? I am not asking for a complete solution, the information if there is an API and what it is called is absolutely sufficient.
I want to solve the following questions:
Which tables are in the database?
Is a given table a root table (not dependant from other tables)?
Is a given table a leaf table (dependant from other tables but no table is dependant from the given table)?
Which tables are dependant from the given table?
On which tables does the given table depend?
I know how to retrieve the mapping between entities and tables:
How to discover fully qualified table column from Hibernate MetadataSources , but I want the relationship between the tables.
In a custom MetadataContributor you can access metadataCollector.getDatabase() which exposes the full relational model to you. You just have so save that into a static volatile variable and then access it later on in your app to do whatever you want to do with it.

How many tables can be mapped in hibernate mapping.?

I am new to hibernate and am using xml file for mapping. I want to map more than 8 tables, is it possible or not ?
I am using mysql for DB. In all that mapping examples they use maximum 3 tables in mapping. If I change the value in one table that has to reflect it on to next one.
For Example I am giving the Username in my Employee Table and use that one in my login table. If I am mapping 2 tables it means, the username in employee table can automatically update to my login table. Is this correct ?
And how many tables am I able to map in single xml file.
A hibernate component may be your solution. Also hibernate definitions can be in separate files and hibernate will figure it out.
https://www.google.com/search?q=hibernate+components

Hibernate one-to-many mapping - to fetch only one mapped record based on a criteria

Problem : There is a transaction table and status table with one-to-many mapping. One transaction can have multiple statuses like failed, partially paid and success. How to fetch the latest status of a transaction.
i.e, If I have a transaction with multiple statuses like failed and success of which success is the latest one. Is there any way to configure the same in hibernate to fetch one record from status table based on date field or any other field?
I have been searching for best way for my problem, though I have some ways to do the same using comparable and compare to in java, I am still wondering if there is any solution that hibernate provides where we can simply configure it in hbm files and get the output.
Thanks in advance.
You can try Filters in hibernate by which you can filter out the data in OneToMany Collection. Also take a look here as an example.

Managing history records in a database

I have a web project that uses a database to store data that is used to generate tasks that would be processed for remote machines to alter that records and store new data. My problem here is that I have to store all that changes on each table but I don't need all these information. For example, a table A could have 5 fields but I only need 2 for historical purposes. Another table B could have 3 and I would have to add another one (date for example). Also, I don't need changes during daily task generation, only the most recent one.
Which is the best way to maintain a change history? Someone told me that a good idea is having two tables, the A (B) table and another one called A_history (B_history) with the needed fields. This is actually what I'm doing, using triggers to insert into history tables but I don't feel comfortable with this approach. My project uses Spring (Spring-data, Hibernate and JPA) and if I change the DB (currently MySQL) I'd have to migrate triggers. Is there a good way to manage history records? Tables could be generated with Hibernate/JPA annotations.
If I maintain the two tables approach, can I add a method to the repository to fetch rows from current table and history table at once?
For this pourpose there is a special Hibernate Envers project. See official documentation here. Just configure it, annotate necessary properties with #Audited annotation and that's all. No need for DB triggers.
One pitfall: if you want to have a record for each delete operation then you need to use Session.delete(entity) way instead of HQL "delete ...".
EDIT. Also take a look into native auditing support of spring data jpa.
I am not a database expert. What I have seen them do boils down to a few ways of approach.
1) They add a trigger to the transactional table that copies inserts and updates to a history table but not deletes. This means any queries that need to include history can be done from the history table since all the current info is there too.
a) They can tag each entry in the history table with time and date and
keep track of all the states of the original records.
b) They can only
keep track of the current state of the original record and then it
settles when the original is deleted.
2) They have a periodic task that goes around and copies data marked as deletable into the history table. It then deletes the data from the transactional table. Any queries in the transactional table have to make sure to ignore the deletable rows. Any queries that need history have to search both tables and merge the results.
3) If the volume of data isn't too large, they just leave everything in one table and mark some entries as historical. Queries have to ignore historical rows. Queries that include history are easy. This may slow down database access as the table grows to include many unused rows but that can sometimes be ameliorated by clever use of indexes.

Best method to archive data using Hibernate

I have a two tables chart and chartHistory which has similar table structure
chart_id NUMERIC(9,0)
chart_ref_id NUMERIC(9,0) NOT NULL
chart_property VARCHAR2(20) NOT NULL
chart_value VARCHAR2(100)
The entries in chart needs to be stored into the chartHistory table, when we get new property/value pairs for chart reference id.
I am planning to implement it using Hibernate in the following way
Get the list of values from CHART table using the chartReferenceId
List<Chart> chartList = chartDao.findChartByVisitRef(chartReferenceId);
( named query : findChartByRef = from Chart chart where chart.chartReferenceId=:chartReferenceId)
Use the retrieved list and build a chartHistoryList using the values from chartList and call the Hibernate method saveAll
chartHistoryDao.saveAll(chartHistoryList);
Once saved, remove the existing entries from the CHART table.
chartDao.deleteAll(chartList);
Build a newChartList for the new entried received, and do a hibernate saveAll
chartDao.saveAll(newChartList);
As you can see this executes four queries ie. for retrieving old records, saving them into the archive table, deleting the old entries and inserting the new values.
I would like to know whether there is a better way to implement this? Something of the sorts insert into .. (select from... ) would be more efficient I guess? Please advice.
Try the envers/audit module of Hibernate which handles all this for you automatically.
The main problem with envers/audit right now is to find the documentation. Envers (the original module) is supposed to be merged with Hibernate code since 3.5 but the core documentation doesn't mention anything about versioning or auditing even though InfoQ insists "Hibernate 4.1 Released With Improved Auditing Support"
So try the outdated documentation linked from the obsolete envers page and hope for the best.
Disclaimer: I haven't used Hibernate or envers for years.

Categories

Resources