Detailed Explanation of Session's update Method in Hibernate Learning Notes V

Detailed Explanation of Session's update Method in Hibernate Learning Notes V

In the previous study, we used Session's save method to transform objects from tansient state to persistent state. Now let's learn Session's update method.

In the hibernate api document, the Session interface provides two overloaded update methods, which are as follows:

1,void update(Object object) : Update the persistent instance with the identifier of the given detached instance.

This method document means that an object in detached state is updated to persistent state according to its unique identifier.

First example: objects in detached state can be update d

This example is a new object, which is persisted by session save method. After persistence, the object enters the detached state, and then we update it, so it can be updated.

package com.hibernate.mode;

    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    import org.junit.AfterClass;
    import org.junit.BeforeClass;
    import org.junit.Test;

    import com.hibernate.model.Teacher;

    public class TeacherTest {
    private static SessionFactory sessionFactory;
    @BeforeClass
    public static void beforeClass(){
        sessionFactory = new Configuration().configure().buildSessionFactory();
    }
    @Test
    public void testUpdate1() {
        Session session=sessionFactory.getCurrentSession();
        session.beginTransaction();
        //The new new object is in the transient s state
        Teacher t=new Teacher();
        t.setName("wuranghao");
        t.setTitle("professior");
        session.save(t);
        session.getTransaction().commit();
        //After commit, the object t enters the detached state. Let's update it with update method.
        Session session2=sessionFactory.getCurrentSession();
        session2.beginTransaction();
        t.setName("haohao");
        session2.update(t);
        session2.getTransaction().commit();
    }
    @AfterClass
    public static void afterClass(){
        sessionFactory.close();
    }

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

The results of the query in the database after running are as follows. From the results, we can see that the object is updated successfully.

Second example: Objects with no unique identifier in the transient state cannot be update d

@Test
    public void testUpdate2() {
        Session session=sessionFactory.getCurrentSession();
        session.beginTransaction();
        Teacher t=new Teacher();
        t.setName("wuranghao");
        t.setTitle("professior");
        //The new object t is in the transient s state at this point to see if it can be update d
        session.update(t);
        session.getTransaction().commit();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Objects in the transient state cannot be update d without a unique identifier ID.

Third example: Objects with unique identifiers in the transient state and records without this Id in the corresponding database table cannot be update d

@Test
    public void testUpdate3() {     
        Teacher t=new Teacher();
        t.setId(2);
        t.setName("wuranghao");
        t.setTitle("professior");
        Session session=sessionFactory.getCurrentSession();
        session.beginTransaction();
        //The new object t is in the transient s state at this point to see if it can be update d
        session.update(t);
        session.getTransaction().commit();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

Fourth example: An object with a unique identifier in the transient state and an Id record with an object set in the database can be update d

The above sentence may not be very easy to understand. That is to say, if there is a record of id=0 in the database, then we can add the object of transient state + the object setId(0), then the object can be update d.

Before testing the following method, the contents of the database are as follows:

@Test
    public void testUpdate3() {     
        Teacher t=new Teacher();
        t.setId(0);
        t.setName("wuranghao");
        t.setTitle("professior");
        Session session=sessionFactory.getCurrentSession();
        session.beginTransaction();
        //The new object t is in the transient s state at this point to see if it can be update d
        session.update(t);
        session.getTransaction().commit();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

After running the test code, the results of the database are as follows:

Fifth example: Changing the property content of the persistent state object automatically update s to the database

The following example is to use Session's get method to export a record of the corresponding Id from the database and convert it into an instance of the Teacher object, where the object is in persistent state.

@Test
    public void testUpdate4() {     
        Session session=sessionFactory.getCurrentSession();
        session.beginTransaction();
        Teacher t=session.get(Teacher.class, 0);//Extract id=0 records from the database and convert them into Teacher object instances.
        //The object from get is the persistent state. If the object of persistent state is changed, it must be automatically update d.
        t.setName("wuwu");
        session.getTransaction().commit();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

This will automatically trigger the update statement, but if the content before and after the change is the same, the update statement will not be triggered. The UPDATE statement is triggered only when the contents of the object in the cache are different from the records of the database.

Summary of Session's update Method

1. Used to update the detached object, and when the update is completed, it changes to persistent state.

2. Updating the transient object will cause an error

3. update the transient object of the unique identifier (e.g. Id) that you have set and the database has corresponding records.

4. Objects in persistent state will automatically trigger the Session update method when commit when the attribute content of the object is changed. One thing to note is that if the content before and after the change is the same, the update statement will not be triggered. The UPDATE statement is triggered only when the contents of the object in the cache are different from the records of the database.

The problem with the update above is that whenever we change several properties of an object, all records are updated when persisted, which is obviously not good.

Here's how to update only the modified fields.

Update partially changed fields

There are three ways to update partially changed fields.

1. xml sets the update attribute of property tag and annotation sets the updatable attribute of @Column.

This method is not flexible, so it is seldom used. No more details will be given below.

2. Use dynamic-update in xml

Note that by setting dynamic-update="true" in the XXX.hbm.xml file, you can achieve partial updates that only change fields.

<class name="Teacher" table="teacher" dynamic-update="true">
    </class>
  • 1
  • 2

The complete configuration file is as follows:

<?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="com.hibernate.model">
    <class name="Teacher" table="teacher" dynamic-update="true">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="name" column="name"/>
        <property name="title"/>
    </class>
    </hibernate-mapping>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

But this approach does not cross Session. In a session, when we add dynamic-update="true" to the XXX.hbm.xml file, we only update the fields we modified. Look at the following examples:

    @Test
    public void testUpdate4() {     
        Session session=sessionFactory.getCurrentSession();
        session.beginTransaction();
        Teacher t=session.get(Teacher.class, 0);//Extract id=0 records from the database and convert them into Teacher object instances.
        //The object from get is the persistent state. If the object of persistent state is changed, it must be automatically update d.
        t.setName("wuwuwuwu");
        session.getTransaction().commit();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

When we run this Test, Hibernate sends out the following MySQL statement, which shows that only the name field has been updated, which is the result we want.

However, when we cross Session, even if we add dynamic-update="true" to the XXX.hbm.xml file, we are not updating only the fields we modified at the second update.

Look at the following examples:

    @Test
    public void testUpdate5() {     
        Session session=sessionFactory.getCurrentSession();
        session.beginTransaction();
        Teacher t=session.get(Teacher.class, 0);//Extract id=0 records from the database and convert them into Teacher object instances.
        //The object from get is the persistent state. If the object of persistent state is changed, it must be automatically update d.
        t.setName("xiao");
        session.getTransaction().commit();
        //Another Session
        Session session2=sessionFactory.getCurrentSession();
        session2.beginTransaction();
        t.setName("xiaoxiao");
        session2.update(t);
        session2.getTransaction().commit();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

The results are as follows:
 
In the example above, dynamic-update="true" was added to the Teacher.hbm.xml file, while the test function had two Sessions. In the second Session, we modified the name attribute of the object in detached state. When we called the update method, we updated not only the name field, but all the fields of the record.

If we want to use this method (i.e. adding dynamic-update="true" to the XXX.hbm.xml file) to update only the fields we modify, but also to cross Session, the solution is that in the second Session, we do not use session 2.update (t) to update, but use session 2.merge (t) to merge updates.

So we don't recommend this method either.

3. Using HQL(EJBQL), this method is recommended.

The example procedure is as follows:

Use Query to update fields.

    @Test
    public void testUpdate6() {     
        Session session=sessionFactory.getCurrentSession();
        session.beginTransaction();
        //org.hibernate.Query     
    //The Teacher of the statement refers to the class, not the table name of the database.
        Query q=session.createQuery("update Teacher t set t.name='wuranghao' where t.id=0");
        q.executeUpdate();
        session.getTransaction().commit();

}from: http://blog.csdn.net/u010412719/article/details/51283926

Keywords: Session Hibernate Database xml

Added by varun8211 on Wed, 22 May 2019 01:50:56 +0300