JPA ve Hibernate'de persistan () ve merge () arasındaki fark nedir?


119

Hazırda Bekletme'de persistan () ve merge () arasındaki fark nedir?

persist() UPDATE & INSERT sorgusu oluşturabilir, örneğin:

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
A a=new A();
session.persist(a);
a.setName("Mario");
session.flush();

bu durumda sorgu şu şekilde oluşturulacaktır:

Hibernate: insert into A (NAME, ID) values (?, ?)
Hibernate: update A set NAME=? where ID=?

böylece persist()yöntem olabilir oluşturmak Bir Ek ve Bir Güncelleme.

Şimdi ile merge():

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();

Veritabanında gördüğüm şey bu:

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Madonna
3           Elvis Presley
4           Luciano Pavarotti

Şimdi kullanarak bir kaydı güncelleyin merge()

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setId(2);
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();

Veritabanında gördüğüm şey bu:

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Luciano Pavarotti
3           Elvis Presley

7
Javadoc, ne yaptıkları ve farkların ne olduğu konusunda çok açık. Okudunuz ve anladınız mı?
skaffman


Yanıtlar:


144

JPA spesifikasyonu , bu işlemlerin anlamlarının çok kesin bir tanımını içerir, javadoc'tan daha iyi:

Bir X varlığına uygulanan kalıcı işlemin anlam bilgisi aşağıdaki gibidir:

  • X yeni bir varlık ise, yönetilir hale gelir. X varlığı, veri tabanına işlem taahhüdü sırasında veya öncesinde veya temizleme işleminin bir sonucu olarak girilecektir.

  • X önceden var olan yönetilen bir varlık ise, kalıcı işlem tarafından yok sayılır. Ancak, X'ten bu diğer varlıklara olan ilişkiler, cascade=PERSISTveya cascade=ALL açıklama öğesi değeriyle açıklanmışsa veya eşdeğer XML tanımlayıcı öğesi ile belirtilmişse , kalıcı işlem X tarafından referans verilen varlıklara basamaklanır .

  • X kaldırılmış bir varlık ise, yönetilir hale gelir.

  • X bağımsız bir nesneyse, EntityExistsExceptionkalıcı işlem başlatıldığında fırlatılabilir EntityExistsExceptionveya ya da başka bir PersistenceExceptionfloş veya tamamlama zamanında atılabilir.

  • X'ten bir ilişkiyle başvurulan tüm Y varlıkları için, Y ile olan ilişkiye basamaklı öğe değeriyle açıklama eklenmişse cascade=PERSISTveya cascade=ALLkalıcı işlem Y'ye uygulanır.


Bir X varlığına uygulanan birleştirme işleminin anlamı aşağıdaki gibidir:

  • X, ayrılmış bir varlık ise, X durumu, aynı kimliğe sahip önceden var olan yönetilen bir varlık örneğine X 'kopyalanır veya X'in yeni bir yönetilen X' kopyası oluşturulur.

  • X yeni bir varlık örneğiyse, yeni bir yönetilen varlık örneği X 'yaratılır ve X durumu, yeni yönetilen varlık örneği X' içine kopyalanır.

  • X kaldırılmış bir varlık örneğiyse, IllegalArgumentExceptionbirleştirme işlemi tarafından bir atılır (veya işlem tamamlama başarısız olur).

  • X yönetilen bir varlık ise, birleştirme işlemi tarafından yok sayılır, ancak birleştirme işlemi, bu ilişkilere basamaklı öğe değeri cascade=MERGEveya cascade=ALLek açıklama eklenmişse, X'ten ilişkiler tarafından referans verilen varlıklara basamaklanır .

  • Basamaklı öğe değerine sahip X'ten ilişkiler tarafından referans verilen tüm Y varlıkları için cascade=MERGEveya cascade=ALLY özyinelemeli olarak Y 'olarak birleştirilir. X tarafından referans verilen tüm bu Y'ler için, X ', Y' referansına ayarlanmıştır. (X yönetiliyorsa, X'in X 'ile aynı nesne olduğunu unutmayın.)

  • X, belirtilmiş cascade=MERGEveya cascade=ALLbelirtilmemiş başka bir Y varlığına referansla X 'ile birleştirilen bir varlık ise, aynı ilişkinin X'ten gezinmesi, Y ile aynı kalıcı kimliğe sahip yönetilen bir Y nesnesine bir referans verir.


Bilgi için teşekkürler. Her iki tanımın da anlamını görüyorum. Ancak soru, aralarındaki farklarla ilgili. Belki de her farklı persistvs davranışı için durumların listesini ve 2 alt bölümü sunun merge.
AlikElzin-kilaka

25

Bu nereden geliyor JPA. Çok basit bir şekilde:

  • persist(entity) bunları DB'ye eklemek için tamamen yeni varlıklar ile kullanılmalıdır (varlık DB'de zaten mevcutsa, EntityExistsException atımı olacaktır).

  • merge(entity) Varlık ayrılmışsa ve değiştirilmişse varlığı kalıcılık bağlamına geri koymak için kullanılmalıdır.


açıklamanıza bir kaynak ekleyebilir misiniz lütfen? Teşekkürler.
AlikElzin-kilaka

@ AlikElzin-kilaka böyle bir açıklama, hatırladığım kadarıyla bir "Java EE 7 Başlangıcı" kitabında buldum.
Krystian

12

Persist yalnızca yeni varlıklarda çağrılmalıdır, birleştirme ise ayrılmış varlıkları yeniden bağlamak içindir.

Atanan oluşturucuyu kullanıyorsanız, kalıcı yerine birleştirme kullanmak gereksiz bir SQL ifadesine neden olabilir ve bu nedenle performansı etkileyebilir.

Ayrıca, yönetilen varlıklar için birleştirme çağrısında da yönetilen varlıklar otomatik hazırda tarafından yönetilir ve bunların devlet tarafından veritabanı kaydı ile senkronize edildiğinden bir hatadır kirli kontrol mekanizması üzerine Sebat Bağlamını ateş basması .


1

En önemli fark şudur:

  • persistYöntem durumunda , kalıcılık bağlamında yönetilecek varlık kalıcılık bağlamında zaten mevcutsa, yenisi göz ardı edilir. (Hiçbir şey olmadı)

  • Ancak mergeyöntem durumunda, kalıcılık bağlamında halihazırda yönetilen varlık yeni varlık (güncellenmiş) ile değiştirilecek ve bu güncellenmiş varlığın bir kopyası geri dönecektir. (Değişikliklerinizi kalıcılık bağlamında yansıtmak istiyorsanız şu andan itibaren bu iade edilen varlık üzerinde herhangi bir değişiklik yapılmalıdır)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.