While I have been able to find information on how Hibernate's transaction work, so the database doesn't corrupted, it has been harder to understand how Hibernate treats an object which is shared between threads, and each thread tries to save it to the database.
This is my theoretical question:
1) I have a Person object with attributes (ssn, name, address). 2) Three threads have a reference to this person object and each thread calls the method savePersonToHibernate(...)
public void savePersonToHibernate(Person person)
{
...
session.saveOrUpdate(person)
...
}
How does Hibernate cope with 3 threads writing the same object to the storage? Does it put all the transactions in a queue so when the first thread creates the row and identifier (set the id) the remaining two thread will only update it with (in this case) no changes? Or will I actually have the chance of having 2 or 3 rows in the database with a current object only referring to the last identifier created?
I hope it makes some kinda sense... I'm making a queue system, and the data needs to be referred to categories which needs to be created on the fly... and if two or more thread get some data which both needs to have the same category created, I'd hate to have duplicated.
I hope this makes sense... what would you do?
hibernate. Session class methods, save & saveOrUpdate is, save generates a new identifier and results in an INSERT query, whereas saveOrUpdate does an INSERT or an UPDATE. Save method stores an object into the database. That means it insert an entry if the identifier doesn't exist, else it will throw error.
saveOrUpdate() Hibernate will check if the object is transient (it has no identifier property) and if so it will make it persistent by generating it the identifier and assigning it to session. If the object has an identifier already it will perform .
You should apply the differnce between save() and saveOrUpdate method in your code to get the best performance: The save() method returns the identifier generated by the database. On the other hand, saveOrUpdate() can do INSERT or UPDATE depending upon whether object exists in database or not.
Difference between saving and persist method in Hibernate 1)The first difference between save and persist is there return type. Similar to save method, persist also INSERT records into the database, but return type of persist is void while return type of save is Serializable Object.
I'm assuming that all mentioned threads use different sessions otherwise you are in trouble as hibernate session is not thread-safe.
Just to make things clear, if all three threads are using the same instance of person and this is a new object you are in trouble as hibernate doesn't do any synchronization when accessing or modifying object. Basically each thread works as though other threads do not exist, so each will first check if person has non null id and try to generate it if id is null and then will assign it to appropriate entity field. Depending on the timing of check-generate-assign in different threads and visibility effects of changes result of concurrent creation is unpredictable.
Let's see what will happen if all threads are using different instances of person but with the same attributes values. In this case each thread will try to create three different rows in database and if there are no unique constraints on the underlying table (like unique name) it will succeed.
Your particular scenario with category creation is not very straightforward to implement. The idea is to try to create category but catch exception if it is already exists. In the latter case read existing category from database and use it. But keep in mind that implementation of conditional insert is not trivial and may be RDBMS dependent. You may fine slightly more complex but related examples for upsert operation for PostgreSQL and SQL Server.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With