Hàm update() và merge() trong hibernate

1. Đơn giản nhất
Hãy hiểu về hàm update như ý nghĩa của cái tên

đó là update một cái gì đó ( đó chính là một đối tượng có giá trị ID rõ ràng)

ví dụ:

Session session = factory.openSession();

        Transaction tx = session.beginTransaction();

        Student student = new Student();
        student.setId(111);
        student.setName("chandra shekhar");
        student.setRollNumber(8469);
        session.update(student);
        tx.commit();
        session.close();

Đoạn code trên chạy đẹp do là đối tượng đã được thiết lập ID. Quá đơn giản
Nếu ID k có trong DB là lỗi ngay

Và nó là lý do sinh ra hàm saveOrUpdate(); :-)))

2. Một chút phức tạp 

Trường hợp này đối tượng được load hoặc get, findxxx,.... từ DB

Session session = factory.openSession();

        Transaction tx = session.beginTransaction();
        Student student = session.load(Student.class, 111);
        student.setName("Johnson");
        session.update(student);
        tx.commit();
        session.close();
Điểm chung là các đối tượng truyền vào update đều đã có ID rõ ràng.
==> cách làm việc của hàm update là nó 

2.5. Vẫn OK nhưng phức tạp hơn

Session session = factory.openSession();

        Student student = (Student) session.get(Student.class, 111);
        session.close();

//          Here student object is in detached state
        student.setName("chandrashekhar");

//        reattaching to session
        Session session2 = factory.openSession();
//        Student student2 = session2.get(Student.class, 111);
        Transaction tx = session2.beginTransaction();

        session2.update(student);
Với trường hợp này vẫn lưu OK nếu trong session2 chưa có thằng Student nào có id =111
Nếu nó có rồi thì xem mục 3 bên dưới


3. Phức tạp hơn một chút

Session session = factory.openSession();

        Student student = (Student) session.get(Student.class, 111);
        session.close();

//          Here student object is in detached state
        student.setName("chandrashekhar");

//        reattaching to session
        Session session2 = factory.openSession();
        Student student2 = session2.get(Student.class, 111);
        Transaction tx = session2.beginTransaction();

        session2.update(student);
Với trường hợp này sẽ xảy ra lỗi. Ví sao???
Rõ ràng là student đã có giá trị ID rồi. Nhưng tại sao. Tại vì khi update được gọi, hibernate nó sẽ tìm trong session đó có đối tượng cùng ID đã ở trong trạng thái Pesistence chưa(trường hợp này là có đối tượng student2 rồi). Dẫn đến Hibernate sẽ không biết làm thế nào. nếu nó lưu đối tượng student xuống DB thì rõ ràng sẽ tạo ra một thằng student nữa ở trong Persistence. Như vậy sẽ có 2 thằng trong persistence cùng trỏ tới 1 ID là 111.

Vậy sẽ xảy ra lỗi nhé. Do hibernate nó sẽ check id đã tồn tại trong persisence chưa

4. Vậy chúng ta phải sửa như thế nào trong trường hợp lỗi như vậy

Vì vậy hàm merge() đã sinh ra để giải quyết vấn đề

5. Dùng hàm merge

Student student = (Student) session.get(Student.class, 111);
        session.close();

//          Here student object is in detached state
        student.setName("John");

//        reattaching to session 
        Session session2 = factory.openSession();
        Student student2 = session2.get(Student.class, 111);
        Transaction tx = session2.beginTransaction();

        Student student3 =session2.merge(student);
Khi đó student3 và student2 sẽ cùng trỏ đến một đối tượng với name = John
khi dùng hàm merge đồng nghĩ đối tượng từ trạng thái detached sẽ được merge vào đối tượng có cùng ID trong persistence 

Như vậy đối tượng student2 ở trên sẽ có giá trị thuộc tính của đối tượng student, cụ thể là thuộc tính name của student2 sẽ có giá trị là John
Như vậy khi session2.commit() thì nó sẽ update giá trị tên mới là John


Kết thúc










Comments

Popular posts from this blog

Fixing the DeepSpeed Import Error While Fine-Tuning the Qwen Model

Amazon Linux 2023 - User data configuration for launch templates to connect to the EKS cluster

How to create ISM policy and rotate logs in opensearch