States of an entity is a very important concept of Hibernate. An entity can have different states. Using Hibernate is different from using SQL. If you call session.save(customerObject) then there is no insert into customer… query into the database. Hibernate will set the id property (if the id is generated) and bind the entity to a persistence context. The persistence context is synchronized with the database when transaction.commit() is called.
This approach has various advantages:
When it is just created and has no primary key, the state is called transient.
Car car = new Car(); car.setName(“Porsche”);
When the session is opened and the object is just saved in or retrieved from the database. This state is called persistent. During this state Hibernate manages the object and saves your changes, if you commit them. Below you can see an example. A car is saved and the name is changed afterwards. As the car is in persistent state, the new name will be saved.
Session session = HibernateSessionFactory.currentSession(); tx = session.beginTransaction(); session.save(car); car.setName(“Peugeot”); tx.commit();
The following code loads a car by id and changes the name. There is no session.update involved. Every object which is loaded by session.get, session.load or a query is in persistent state. It is stored in the persistence context of the session. When tx.commit() is called, Hibernate will flush the persistence context and all not yet written insert, update and delete statements are executed.
Session session = HibernateSessionFactory.currentSession(); tx = session.beginTransaction(); Car car = (Car) session.get(Car.class, 4711); car.setName(“Peugeot”); tx.commit();
When the session was closed, the state changes to detached. The object is detached from its session.
Understanding these states is important in order to know how to deal with instances. Imagine you do a web dialogue
Now, you would normally save the changes. But you cannot just call
transaction = session.beginTransaction(); car.setname(newName); transaction.commit();
If you want to save the changes, you have to reattach your instance. This means the instance must be brought to a persistent state. You can not save an instance when it is not in persistent state, except if it was transient before and has no primary key set.
You must reattach an object before you can update it.
transaction = session.beginTransaction(); session.buildLockRequest(LockOptions.NONE).lock(car); car.setname(newName); transaction.commit();
The following picture show the change of status how it could happen in a web application.
You might be aware of the method session.lock(car). It is deprecated since Hibernate 3.6.