Ini dari bagian 10.7. Deteksi status otomatis dari Dokumentasi Referensi Hibernasi:
saveOrUpdate () melakukan hal berikut:
- jika objek tersebut sudah ada dalam sesi ini, jangan lakukan apa pun
- jika objek lain yang terkait dengan sesi tersebut memiliki pengenal yang sama, lemparkan pengecualian
- jika objek tidak memiliki properti pengenal, simpan ()
- jika pengenal objek memiliki nilai yang ditetapkan ke objek yang baru dibuat, simpan () itu
- jika objek diversi (oleh <version> atau <timestamp>), dan nilai properti versi adalah nilai yang sama yang ditetapkan ke objek yang baru dibuat, simpan () itu
- jika tidak perbarui () objek
dan merge () sangat berbeda:
- jika ada instance persisten dengan pengenal yang sama yang saat ini terkait dengan sesi, salin status objek yang diberikan ke instance persisten
- jika tidak ada instance persisten yang saat ini terkait dengan sesi, coba muat dari database, atau buat instance persisten baru
- contoh persisten dikembalikan
- contoh yang diberikan tidak menjadi terkait dengan sesi, itu tetap terlepas
Anda harus menggunakan Merge () jika Anda mencoba untuk memperbarui objek yang pada satu titik terlepas dari sesi, terutama jika mungkin ada contoh persisten dari objek yang saat ini terkait dengan sesi. Jika tidak, menggunakan SaveOrUpdate () dalam kasus itu akan menghasilkan pengecualian.
SaveOrUpdateCopy
tidak sama denganSaveOrUpdate
. Saya tidak yakin apakah penanya ingin membandingkanMerge
yang pertama atau yang terakhir.SaveOrUpdateCopy
adalah metode yang sekarang sudah usang yang melakukan penggabungan di NHibernate sebelumMerge
diimpor.Seperti yang saya pahami,
merge()
akan mengambil objek yang mungkin tidak terkait dengan sesi saat ini, dan copy negara (nilai properti, dll) untuk objek yang adalah terkait dengan sesi saat ini (dengan PK yang sama nilai / identifier, dari kursus).saveOrUpdate()
akan memanggil Simpan atau Perbarui pada sesi Anda, berdasarkan nilai identitas objek tertentu.sumber
SaveOrUpdateCopy()
sekarang tidak digunakan lagi sejak NHibernate 3.1.Merge()
harus digunakan sebagai gantinya.sumber
SaveOrUpdateCopy
yang ditandaiObsolete
, bukanSaveOrUpdate
. Tampaknya ada banyak kebingungan antara dua metode berbeda dalam pertanyaan ini dan jawaban berikutnya.** Update()**
: - jika Anda yakin bahwa sesi tersebut tidak berisi instance yang sudah ada dengan pengenal yang sama, gunakan pembaruan untuk menyimpan data dalam mode hibernasi
** Merge()**
: -jika Anda ingin menyimpan modifikasi Anda setiap saat tanpa mengetahui tentang status sesi, gunakan merge () dalam hibernate.
sumber
Saya menemukan tautan ini yang cukup bagus menjelaskan jenis pengecualian ini:
Apa yang berhasil bagi saya adalah sebagai berikut:
cascade="merge"
SaveOrUpdate
objek anak / dependen terlebih dahulu sebelum menetapkannya ke objek induk.SaveOrUpdate
objek induk.Namun, solusi ini memiliki keterbatasan. yaitu, Anda harus berhati-hati dalam menyelamatkan anak Anda / objek dependen alih-alih membiarkan hibernasi melakukannya untuk Anda.
Jika ada yang punya solusi yang lebih baik, saya ingin melihat.
sumber
@Entity @Table(name="emp") public class Employee implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="emp_id") private int id; @Column(name="emp_name") private String name; @Column(name="salary") private int Salary; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getSalary() { return Salary; } public void setSalary(int salary) { this.Salary = salary; } public int getId() { return id; } public void setId(int id) { this.id = id; } } public enum HibernateUtil { INSTANCE; HibernateUtil(){ buildSessionFactory(); } private SessionFactory sessionFactory=null; public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } private void buildSessionFactory() { Configuration configuration = new Configuration(); configuration.addAnnotatedClass (TestRefresh_Merge.Employee.class); configuration.setProperty("connection.driver_class","com.mysql.jdbc.Driver"); configuration.setProperty("hibernate.connection.url", "jdbc:mysql://localhost:3306/hibernate"); configuration.setProperty("hibernate.connection.username", "root"); configuration.setProperty("hibernate.connection.password", "root"); configuration.setProperty("dialect", "org.hibernate.dialect.MySQLDialect"); configuration.setProperty("hibernate.hbm2ddl.auto", "update"); configuration.setProperty("hibernate.show_sql", "true"); configuration.setProperty(" hibernate.connection.pool_size", "10"); /* configuration.setProperty(" hibernate.cache.use_second_level_cache", "true"); configuration.setProperty(" hibernate.cache.use_query_cache", "true"); configuration.setProperty(" cache.provider_class", "org.hibernate.cache.EhCacheProvider"); configuration.setProperty("hibernate.cache.region.factory_class" ,"org.hibernate.cache.ehcache.EhCacheRegionFactory"); */ // configuration StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()); sessionFactory = configuration.buildSessionFactory(builder.build()); setSessionFactory(sessionFactory); } public static SessionFactory getSessionFactoryInstance(){ return INSTANCE.getSessionFactory(); } } public class Main { public static void main(String[] args) { HibernateUtil util=HibernateUtil.INSTANCE; SessionFactory factory=util.getSessionFactory(); //save(factory); retrieve(factory); } private static void retrieve(SessionFactory factory) { Session sessionOne=factory.openSession(); Employee employee=(Employee)sessionOne.get(Employee.class, 5); sessionOne.close(); // detached Entity employee.setName("Deepak1"); Session sessionTwo=factory.openSession(); Employee employee1=(Employee)sessionTwo.get(Employee.class, 5); sessionTwo.beginTransaction(); sessionTwo.saveOrUpdate(employee); // it will throw exception //sessionTwo.merge(employee); // it will work sessionTwo.getTransaction().commit(); sessionTwo.close(); } private static void save(SessionFactory factory) { Session sessionOne=factory.openSession(); Employee emp=new Employee(); emp.setName("Abhi"); emp.setSalary(10000); sessionOne.beginTransaction(); try{ sessionOne.save(emp); sessionOne.getTransaction().commit(); }catch(Exception e){ e.printStackTrace(); }finally{ sessionOne.close(); } } }
sumber