persist là gì

Khi dùng JPA, quy trình quy đổi hiện trạng của thực thể(entity) sẽ tiến hành JPA – Hibermate quy đổi tự động hóa lịch sự những câu mệnh lệnh SQL. Trong nội dung bài viết này tất cả chúng ta tiếp tục nằm trong lần loại về persistmerge nhập JPA – Hibernate được cho phép tạo nên mới nhất và update dự liệu xuống database. 

Bạn đang xem: persist là gì

Hàm Persist nhập JPA – Hibernate

Persist dùng nhằm fake một entity kể từ hiện trạng transitent lịch sự persistence(persistence entity) được vận hành bởi Hibernate. Vì vậy persist chỉ được dùng với transitent entity (một thực thể mới nhất không tồn tại mối quan hệ với 1 loại tài liệu nào là bên dưới database).

Ví dụ tất cả chúng ta thực thi đua đoạn code sau:

Post post = new Post(); post.setTitle("High-Performance Java Persistence"); entityManager.persist(post); LOGGER.info("The post entity identifier is {}", post.getId()); LOGGER.info("Flush Persistence Context"); entityManager.flush();

Hibernate tiếp tục fake Post nhập Persistence Context. Một câu mệnh lệnh INSERT sẽ tiến hành thực thi đua ngay lập tức khi tê liệt hoặc đợi cho tới thời gian flush-time.

flush-time là thời gian tuy nhiên JPA-Hibernate đồng nhất hoá những thay cho thay đổi của những entity xuống database. JPA và Hibernate tương hỗ một vài kế hoạch nhằm xác lập flush-time. Ví dụ nhập Hibernate và JPA dùng khoác lăm le flush-before-query, bởi đa số những câu truy vấn đều cần liên kết cho tới database, đó cũng là thời gian đảm bảo chất lượng nhằm thực thi đua những thay cho thay đổi bên trên entity xuống database.

Persist với Identity

Nếu entity đang được dùng IDENTITY generator.

@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;

Thì SQL INSERT tiếp tục thực thi đua ngay lập tức tức khắc, và Hibernate tiếp tục về thành phẩm sau

INSERT INTO post (id, title) VALUES (DEFAULT, 'High-Performance Java Persistence') -- The Post entity identifier is 1 -- Flush Persistence Context

Note:

  • Khi một entity được persist, Hibernate tiếp tục tăng nó nhập Persistence Context đấy là điểm vận hành những persist entity trải qua một Map với key là khoá chủ yếu của entity và Entity-Class-Type. Ví dụ với Post thì key được xem là Post class và tính chất ID.
  • Đối với khoá chủ yếu dùng IDENTITY generator thì cơ hội độc nhất nhằm xác lập độ quý hiếm mang lại khoá đó là thực thi đua SQL INSERT. Vì vậy SQL INSERT được thực thi đua ngay lập tức tức khắc Lúc tất cả chúng ta gọi persist method tuy nhiên ko cần đợi cho tới flush-time.
  • Bởi nguyên do bên trên tuy nhiên Hibernate vô hiệu hoá chức năng JDBC batch insert cho những entity dùng Identity generator.

Persist với Sequence

Khi dùng SEQUENCE generator, SQL INSERT hoàn toàn có thể đợi cho tới flush-time. Và hibermate hoàn toàn có thể tối ưu hoá hiệu xuất bằng phương pháp vận dụng JDBC batch insert. 

CALL NEXT VALUE FOR 'hibernate_sequence' -- The post entity identifier is 1 -- Flush Persistence Context INSERT INTO post (title, id) VALUES ('High-Performance Java Persistence', 1)

Hàm merge nhập JPA – Hibernate

Merge dùng làm fake một entity kể từ hiện trạng detached (detached entity) lịch sự persistence và update lại những thay cho thay đổi bên trên tê liệt đối với loại tài liệu ứng bên dưới database. Vì thế Merge method nên làm dùng với detached entity.

Giả sử tất cả chúng ta thực đoạn code sau nhập một phiên của EntityManager.

Post post = doInJPA(entityManager -> { Post _post = new Post(); _post.setTitle("High-Performance Java Persistence"); entityManager.persist(_post); return _post; });

Sau Lúc thực thi đua đoạn mã bên trên, một Post entity được tăng xuống database và entityManager bị đóng góp lại, thời điểm này Post entity tiếp tục fake lịch sự hiện trạng detached. Hibermate sẽ không còn ghi nhận ngẫu nhiên thay cho thay đổi nào là bên trên nó. Nếu tất cả chúng ta thực thi đua một vài thay cho thay đổi và ham muốn nó được đồng nhất xuống database, việc quan trọng là tăng nó vào trong 1 Persistence Context mới nhất.

post.setTitle("High-Performance Java Persistence Rocks!"); doInJPA(entityManager -> { LOGGER.info("Merging the Post entity"); Post post_ = entityManager.merge(post); });

Khi đoạn code bên trên triển khai, hibernate tiếp tục trả về thành phẩm như sau

-- Merging the Post entity SELECT p.id AS id1_0_0_ , p.title AS title2_0_0_ FROM post p WHERE p.id = 1 UPDATE post SET title='High-Performance Java Persistence Rocks!' WHERE id=1

Đầu tiên Hibernate tiếp tục thực thi đua câu SELECT trước nhằm lấy hiện trạng tiên tiến nhất kể từ database, tiếp cho tới nó sẽ bị sao chép những hiện trạng kể từ detached entity nhập entity vừa mới được lấy lên kể từ database.

Xem thêm: mùa hoa rơi gặp lại chàng tập 1

Đối với những entity dùng IDENTITYSEQUENCE generator, chúng ta cũng có thể dùng merge nhằm persist một entity.

Xem ví dụ sau đây Lúc Post entity dùng khoá chủ yếu giá tốt trị thủ công

@Id private Long id;

Nếu tất cả chúng ta dùng merge thay cho persist method

doInJPA(entityManager -> { Post post = new Post(); post.setId(1L); post.setTitle("High-Performance Java Persistence"); entityManager.merge(post); });

Hibernate tiếp tục thực thi đua câu mệnh lệnh SELECT xuống database nhằm đáp ứng không tồn tại loại tài liệu nào là ứng với Post entity.

SELECT p.id AS id1_0_0_, p.title AS title2_0_0_ FROM post p WHERE p.id = 1 INSERT INTO post (title, id) VALUES ('High-Performance Java Persistence', 1)

Chúng tao hoàn toàn có thể xung khắc yếu tố này bằng phương pháp thêm 1 tính chất @Version mang lại entity, đó cũng là cơ hội đảm bảo chất lượng nhằm đáp ứng những tài liệu vẫn tồn tại qua quýt những đợt update.

@Version private Long version;

Lưu ý hãy dùng wrapper class nhằm Hibernate hoàn toàn có thể đánh giá null mang lại tính chất @Version thay vì thế dùng loại tài liệu nguyên vẹn thuỷ.

Một ví dụ vận dụng quy tắc bên trên nhập Spring Data bên phía trong code tổ chức thực hiện của save() method

@Transactional public <S extends T> S save(S entity) { if (entityInformation.isNew(entity)) { em.persist(entity); return entity; } else { return em.merge(entity); } }

Hàm entityInformation.isNew(entity) tiếp tục trả về true nếu như khóa chủ yếu notnull, thì khi này save() method tiếp tục gọi cho tới merge thay cho persist như tất cả chúng ta mong ước. Trong tình huống này tất cả chúng ta tiếp tục hạn chế được một câu mệnh lệnh SELECT.

Sai lầm Lúc dùng save method nhập Spring

Đoạn code sau tế bào miêu tả việc tất cả chúng ta ham muốn lấy một Post entity kể từ database lên và update lại title.

@Transactional public void savePostTitle(Long postId, String title) { Post post = postRepository.findOne(postId); post.setTitle(title); postRepository.save(post); }

Tuy nhiên nhập tình huống này, save method được dùng gần như là bất nghĩa. Nếu tất cả chúng ta xoá nó rời khỏi Hibermate vẫn tiếp tục thực thi đua một câu mệnh lệnh UPDATE xuống database chính vì entity này đang rất được Hibermate vận hành, từng thay cho thay đổi bên trên nó đều được đồng nhất xuống database miền là EntityManager lúc này đang làm việc.

Tóm lược

Trong Lúc dùng save method nhập spring khá tiện lợi, thì chúng ta tránh việc gọi merge method cho những entity vừa mới được khởi tạo nên hoặc và được vận hành bởi hibernate. Các entity mới nhất nên gọi với persist và merge cho những deteach entity ham muốn update lại những thay cho thay đổi.

Nguồn tham ô khảo

https://vladmihalcea.com/jpa-persist-and-merge/

Xem thêm: giáo dục kinh tế và pháp luật