Let's say you have a database table name table1 with columns name and surname. Two different clients open the same view from the java application and get the data for same person at the same time.
1) First client changed the name and pressed save button to update database record.
2) Client2 still sees the old record on the screen and then pressed to save button to change the surname.
It actually overwrite the record by old name. I think to check and get the latest data before updating the database when I click button but I do not like this solution because of making a second query before update.
So how can we solve this problem by using Hibernate and without using Hibarnete. Any idea?
Of course if you do not want that something will be overridden, then you have to check the data before an update. But it will be not always a real query with a good caching strategy. You could also use a timestamp with last update to compare it easier. Another strategy would be to lock the entities when the first user will read them. But that is normally not a good design for web applications or you have to integrate a messaging service, which will all user inform for an update who actually have open that entity. But I think that is not so easy to implement and a more advanced feature.
In short, compare the timestamp of an entity and if already updated, then compare the changes and show them for the user who wanted update that entity.
Related
I'm using java and I have a software that registers a patient and save it in a database, but there are some attributes that must be changed every time and I dont know how to do it:
My table(patients):
1.Name: (patient's name) [varchar].
2.CPF:(is a personal number that Brazilians uses to identify yourself, everybody has one), [varchar].
3.Notes:(patient's progress after the scessions) the patient will receive a bunch of notes, so it should be an array.
After one note saved, I would like to save more after...
As after the update, you Need to update the notes for the patient. So what you can do is create a table called Patient_Notes where it will have the reference from the patient table (patient_id). By this, you can store all the notes for the patient. And also you won't need to update the same. You can just fetch the last one and also you will the have the records for all the notes that have been made.
If I something like the following:
#Relation(parentColumn = "id", entityColumn = "fk_id", entity = User.class)
private List<User> users;
This list is a model which gets updated via LiveData.
But I want to be able to update this when I detect changes to the User table. Right now, it only picks up what exists in the DB, but whenever an update happens to the user table, this list does not get updated. Any suggestions?
You have not been very specific in what you are doing or want (which database you use, who is updating the database...).
But I want to be able to update this when I detect changes to the User
table. Right now, this only picks up what exists in the DB but
whenever an update happens to the user table, this list does not get
updated. Any suggestions?
Option 1
If you are doing the update/insert/delete in the same app as the List users, then you can easily update your List in your code.
Option 2
If another app/service is updating the database, I suggest you use a trigger to update your List.
See http://www.coderconsole.com/2015/02/android-sqlite-trigger-demo.html for an example.
Detecting the change in Java is tricky, see Calling a Java method from a sqlite trigger (android) .
Here is an example where you use a ContentObserver to monitor your Sqlite database (the flat file itself) https://gist.github.com/JBirdVegas/3874450
Option 3
If another app/service is updating the database, you can use a BroadcastReceiver to pick up the changes.
I have the following table in my db:
CREATE TABLE document (
id INT PRIMARY KEY AUTOINCREMENT,
productModelId INT NOT NULL,
comment VARCHAR(50),
CONSTRAINT FK_product_model FOREIGN KEY (productModelId) REFERENCES product_model(id),
)
Of course, real table is much more complicated, but this is enough to understand the problem.
Our users want to see the number of the document when they click button "new". So, in order to do that, we have to create object in db and send to client that object. But, there is a problem. We need to know productModelId before we save the object in db. Otherwise we will have an sql exception.
I see two possible variants (both are ugly, really):
To show modal list with product models to user and after that create object in database with productModelId chosen by user.
To create a temporary number and after that to save the object in db when user finishes editing the document and saves id. We also need to remove NOT NULL case and validate this somwhere in code.
The first way is bad because we have too much modals in our application. Our UI is too heavy with them.
The second variant is ugly because our database is not consistent without all the checks.
What can you suggest we do? Any new solutions? What do you do in your apps? May be some UI tips. We are using the first variant at the moment.
Theory says that the id you use on your database should not be a relevant information, so the user should not see it if not well hidden in an URL or similar, so you should not display it to the user, and the problem you have is one possible confirmation of this theory.
Right now the solution you have is partially correct: it satisfies technical requirements, but is still bad because if the user doesn't complete the insert you'll end up with the DB having empty records (meaning, with ID and foreign key ok, but all other fields empty or with useless default values), so you are basically circumventing the database validations.
There are two better solutions, but both require you to review your database.
The first is not to use the id as something to display to the user. Use another column, with another "id", declare it unique on the database, generate it at application, display it to the user, and then use this other "id" (if it's unique, it is effectively an id) wherever needed.
The second one is the one that is being used often cause it does not require a central database or other authority to check uniqueness of ids, so scales better in distributed environments.
Drop the use of the common "id int" auto-incremented or not, and use UUIDs. Your id will be a varchar or a binary, an UUID implementation (like java.util.UUID, but you can find in other languages) will generate a unique id by itself whenever (and wherever, even on the client for example) you need it, and then you supply this id when saving.
We make it the following way.
Created table id_requests with fields issue_type_id and lastId. We need this in order to avoid the situation when two users hit the button 'new' and get the same ids.
And of course we added field innerNum to all the tables we use this feature in.
Thank you!
I have an employee and a corresponding employee history table.
Both the tables have same structure. History table is used to track the historical changes made to the employee over a period of time.
Now, I need to add an undo function to the changes made to the employee.
e.g. Employees title is changed on 1st August. Now, This will update the employees title in Employee table and insert an corresponding history record in employee_history table.
Now, I need to undo this change. Employee edit page will have a list of changes made to employee datewise with an undo button beside it.
Clicking on undo should revert changes in Employee table to previous value. Also I think the record in history table which says title is changed, should also be removed.
Also when I revert tghe changes to employee table i.e. revert title to previous title, this will fire an insert to history table, which I dont want.
I am not sure what is the best possible way to do this.
Any suggestions will be helpful.
In case you want to implement a "persistent" undo - one that would survive an application restart/session timeout, you should consider extending your DB schema width timestamp fields and either delete the last entry or replace it with an appropriate earlier entry.
A "light" version would be using a stack to store last interactions, including the original and the new value. You could persist the stack on session invalidation of course to combine both approaches. This seems to be what you are actually doing.
You could extend this solution by creating and storing or exporting SQL migration scripts for each change, recording the change and, if possible, the opposite action. So you could even transfer the scripts between application instances and environments and would have a complete "replayability" of your DB states.
tl;dr - it looks like you have already implemented a good solution
I would suggest using a flag telling the trigger/history logic to keep off while you have your undo running and not writing history data.
Normally this would be done by serializer-class feeding from your history table and restoring employee data and later cleaning up history-entries/unlocking history again.
You could maybe use the rollback feature of the transaction.
I need the sample program in Java for keeping the history of table if user inserted, updated and deleted on that table. Can anybody help in this?
Thanks in advance.
If you are working with Hibernate you can use Envers to solve this problem.
You have two options for this:
Let the database handle this automatically using triggers. I don't know what database you're using but all of them support triggers that you can use for this.
Write code in your program that does something similar when inserting, updating and deleting a user.
Personally, I prefer the first option. It probably requires less maintenance. There may be multiple places where you update a user, all those places need the code to update the other table. Besides, in the database you have more options for specifying required values and integrity constraints.
Well, we normally have our own history tables which (mostly) look like the original table. Since most of our tables already have the creation date, modification date and the respective users, all we need to do is copy the dataset from the live table to the history table with a creation date of now().
We're using Hibernate so this could be done in an interceptor, but there may be other options as well, e.g. some database trigger executing a script, etc.
How is this a Java question?
This should be moved in Database section.
You need to create a history table. Then create database triggers on the original table for "create or replace trigger before insert or update or delete on table for each row ...."
I think this can be achieved by creating a trigger in the sql-server.
you can create the TRIGGER as follows:
Syntax:
CREATE TRIGGER trigger_name
{BEFORE | AFTER } {INSERT | UPDATE |
DELETE } ON table_name FOR EACH ROW
triggered_statement
you'll have to create 2 triggers one for before the operation is performed and another after the operation is performed.
otherwise it can be achieved through code also but it would be a bit tedious for the code to handle in case of batch processes.
You should try using triggers. You can have a separate table (exact replica of your table of which you need to maintain history) .
This table will then be updated by trigger after every insert/update/delete on your main table.
Then you can write your java code to get these changes from the second history table.
I think you can use the redo log of your underlying database to keep track of the operation performed. Is there any particular reason to go for the program?
You could try creating say a List of the objects from the table (Assuming you have objects for the data). Which will allow you to loop through the list and compare to the current data in the table? You will then be able to see if any changes occurred.
You can even create another list with a object that contains an enumerator that gives you the action (DELETE, UPDATE, CREATE) along with the new data.
Haven't done this before, just a idea.
Like #Ashish mentioned, triggers can be used to insert into a seperate table - this is commonly referred as Audit-Trail table or audit log table.
Below are columns generally defined in such audit trail table : 'Action' (insert,update,delete) , tablename (table into which it was inserted/deleted/updated), key (primary key of that table on need basis) , timestamp (the time at which this action was done)
It is better to audit-log after the entire transaction is through. If not, in case of exception being passed back to code-side, seperate call to update audit tables will be needed. Hope this helps.
If you are talking about db tables you may use either triggers in db or add some extra code within your application - probably using aspects. If you are using JPA you may use entity listeners or perform some extra logic adding some aspect to your DAO object and apply specific aspect to all DAOs which perform CRUD on entities that needs to sustain historical data. If your DAO object is stateless bean you may use Interceptor to achive that in other case use java proxy functionality, cglib or other lib that may provide aspect functionality for you. If you are using Spring instead of EJB you may advise your DAOs within application context config file.
Triggers are not suggestable, when I stored my audit data in file else I didn't use the database...my suggestion is create table "AUDIT" and write java code with help of servlets and store the data in file or DB or another DB also ...