This is the 12th day of my participation in the August More Text Challenge. For details, see:August is more challenging

State classification

In the Hibernate framework, to manage persistence classes, Hibernate divides them into three states:

  1. Transient Object
  2. Persistent Object
  3. Detached (Detached Object)

There are a lot of people who seem to be confused about these concepts and the transition between them, so this article is to solve these problems, you will not come to me after reading. (Just kidding ~~)

A detailed description

Let’s first look at the three states in detail:

1, transient tense

Objects created by the new operator are considered transient if they are not yet associated with a Session in Hibernate. Transient objects are not persisted into the database, nor are they given a persistence identifier, and are garbage collected if a reference to a transient object is lost in the program.

2. Persistent state

Persistent instances have corresponding records in the database and have a persistence identity. Persistent instances can be either newly saved or newly loaded. Either way, the persistent object must be associated with the specified Session object.

3. Out-of-tube state

An instance was once in a persistent state, but as the Session associated with it is closed, the object becomes unmanaged. References in the out-of-control state remain valid, and the object can continue to be modified. If you re associate an unmanaged object with a Session, the unmanaged object will revert to a persistent state.

Transient tense Persistent state Pipe of state
Whether to save in the Session cache x Square root x
Whether the corresponding record exists in the database x Square root Square root

Such as:

public class HibernateTest {

	private Session session;
	private Transaction transaction;

	@Before
	public void before(a) {
		session = HibernateUtil.getSession();
		transaction = session.beginTransaction();
	}
	
	@After
	public void after(a) {
		transaction.commit();
		session.close();
	}

	@Test
	public void test(a) {
		Person p = new Person();
		p.setPname("Zhang");
		p.setAge(20); session.save(p); }}Copy the code

So in an example like this, the process from creating the Person object to assigning the name and age properties is transient, and the session object is transitioned from transient to persistent only after the session object’s save() method is called. When the session is closed, the object changes from persistent to unmanaged.

Transitions between object states

Now that we know about the three object states, let’s take a look at how these three object states magically transition from one to the other.

Transient < — > persistent

We know that when an object is created, it is transient, so how does it become persistent? Here’s an example:

@Test
public void test(a) {
	Person p = new Person();
	p.setPid(2);
	p.setPname("Bill");
	p.setAge(30);
	session.save(p);
	//session.saveOrUpdate(p);
}
Copy the code

When the name and age attributes are assigned, the object is still in the transient tense, as mentioned earlier. Note, however, that when the primary key, the Pid attribute, is assigned, the object is no longer in the transient state, but is converted to the untubed state, since the persistence identity is present but not associated with the Session. The session object is converted to a persistent state only when its update() or saveOrUpdate() methods are called. Of course, calls to the session object get(), load(), query, find() and other methods to query from the database will also be in the persistent state. A persistent object changes from persistent to transient only when the session object calls the delete() method to delete it from the database.

Persistent state < — > Out-of-tube state

When the close(), clear() and other methods of the session object are called, the associated objects of the session will be converted from the persistent state to the unmanaged state, and these objects will lose their association with the session. To switch from untubeable to persistent, simply call methods like save(), saveOrUpdate(), and so on.

Transient tense — > off tube state

As mentioned earlier, when an object is created and the setXXX() method is called to set the primary key property, the object is transitioned from transient to untubeable, provided that the primary key exists in the database.

Object lifecycle

The following is an analysis of the process of creating an object and saving it to the database:

try {
	Session session = HibernateUtil.openSession();
	// Start the transaction
	session.beginTransaction();
	// The person object enters a transient state
	Person p = new Person();
	p.setPname("Fifty");
	p.setAge(40);
	// The person object enters the persistent state
	session.save(p);
	// Commit the transaction, implicitly including the action of session.flush()
	session.getTransaction().commit();
	// When the submission is complete, the person is in a free state
} catch (HibernateException e) {
	e.printStackTrace();
	if(session ! =null)
	session.getTransaction().rollback();
} finally {
	if(session ! =null)
	session.close();
}
Copy the code

When an Object is instantiated, the Object is in a transient state. When session.save(Object) is called, the Object is added to the session cache and entered the persistent state. At this time, the corresponding record does not exist in the database. When the session commits the transaction, the database generates the corresponding record, but there is a point to note here, because the transaction commits by default to call the session.flush() method to clear the cache, which is equivalent to calling the clear() method. The object goes from persistent to untubed. Objects in untubed state are destroyed by garbage collection. This is the entire life cycle of an object from creation to saving to the database.

other

Having an understanding of object state can explain many phenomena. In Hibernate, SQL statements are generated automatically only when objects are transited from other states to persistent states. Otherwise, SQL statements are not generated repeatedly. This is the key to the efficiency of Hibernate framework. Such as:

@Test
public void test2(a) {
	Session session = HibernateUtil.getSession();
	Transaction transaction = session.beginTransaction();
	Person p = new Person();
	p.setPname("Bill");
	p.setAge(30);
	session.save(p);
	p.setPname("Fifty");
	session.update(p);
	transaction.commit();
	session.close();
}
Copy the code

I am in transaction.com MIT (); This statement makes a power cut and debugs.As you can see, the console outputs only one SQL statement, the insert generated when the save() method is executed, but the update() method generates no SQL. This is because when the update() method is executed, the Hibernate framework determines the state of the current object. It finds that the object is in a persistent state, so it does not generate the SQL repeatedly. It just changes the value of the persistent object, and then generates the update statement when the transaction commits by calling the commit() method.

Let’s move on to an example:

@Test
public void test2(a) {
	Session session = HibernateUtil.getSession();
	Transaction transaction = session.beginTransaction();
	Person p = new Person();
	p.setPname("Zhang");
	p.setAge(30);
	session.save(p);// The object is converted from transient to persistent, and the SQL statement is generated
		
	p.setPname("Fifty");
	session.save(p);// In this case, the object is persistent and no SQL statement is generated
	
	p.setPname("Daisy");
	session.update(p);// In this case, the object is persistent and no SQL statement is generated
	
	transaction.commit();
	session.close();
}
Copy the code

You know, it doesn’t matter which method you call, the key is the state of the object, and only the SQL statement is generated when the object is converted to a persistent state. So the above program will still only produce two SQL pieces, one from the save() method and one from the commit() method. The console information is as follows:

Hibernate: insert into PERSON (PNAME, AGE) values (? ,?) Hibernate: update PERSON set PNAME=? , AGE=? where PID=?Copy the code

Understanding the three states of Hibernate will make it easier to understand how Hibernate works, which can help you to locate problems in your development.