Czasami zauważam, że w przypadku moich obiektów rodzic / dziecko lub relacji wiele-do-wielu, muszę zadzwonić albo SaveOrUpdate
albo Merge
. Zwykle, gdy muszę zadzwonić SaveOrUpdate
, wyjątek, który otrzymuję podczas wywoływania, dotyczy Merge
tego, że obiekty przejściowe nie są zapisywane jako pierwsze.
Proszę wyjaśnić różnicę między nimi.
źródło
SaveOrUpdateCopy
to nie to samo coSaveOrUpdate
. Nie jestem pewien, czy pytający chciał porównaćMerge
to pierwsze, czy drugie.SaveOrUpdateCopy
jest przestarzałą metodą, która przedMerge
importem dokonała połączenia z NHibernate .Jak rozumiem,
merge()
weźmie obiekt, który może nie być powiązany z bieżącą sesją i skopiuje jego stan (wartości właściwości itp.) Do obiektu, który jest powiązany z bieżącą sesją (z tą samą wartością PK / identyfikatorem, kierunek).saveOrUpdate()
wywoła Save lub Update w Twojej sesji na podstawie wartości tożsamości danego obiektu.źródło
SaveOrUpdateCopy()
jest obecnie przestarzałe od NHibernate 3.1.Merge()
należy użyć zamiast tego.źródło
SaveOrUpdateCopy
jest zaznaczoneObsolete
, a nieSaveOrUpdate
. Wydaje się, że w tym pytaniu i kolejnych odpowiedziach istnieje wiele nieporozumień między tymi dwiema różnymi metodami.** Update()**
: - jeśli masz pewność, że sesja nie zawiera już trwałej instancji o tym samym identyfikatorze, użyj aktualizacji, aby zapisać dane w hibernacji
** Merge()**
: -jeśli chcesz zapisać swoje modyfikacje w dowolnym momencie, nie wiedząc o stanie sesji, użyj funkcji merge () w trybie hibernacji.
źródło
Znalazłem ten link, który wykonał całkiem niezłą robotę, wyjaśniając tego typu wyjątek:
Dla mnie zadziałało:
cascade="merge"
SaveOrUpdate
obiekt podrzędny / zależny najpierw przed przypisaniem go do obiektu nadrzędnego.SaveOrUpdate
obiekt nadrzędny.Jednak to rozwiązanie ma ograniczenia. tj. musisz zadbać o uratowanie swojego dziecka / obiektu zależnego, zamiast pozwolić na hibernację robiąc to za Ciebie.
Jeśli ktoś ma lepsze rozwiązanie, chciałbym zobaczyć.
źródło
@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(); } } }
źródło