Иногда я замечаю, что с моими родительскими / дочерними объектами или отношениями многие-ко-многим мне нужно вызвать либо SaveOrUpdate
или Merge
. Обычно, когда мне нужно позвонить SaveOrUpdate
, исключение, которое я получаю при вызове Merge
, связано с тем, что временные объекты не сохраняются в первую очередь.
Пожалуйста, объясните разницу между ними.
источник
SaveOrUpdateCopy
это не то же самое, чтоSaveOrUpdate
. Я не уверен, хотел ли спрашивающий сравнитьMerge
первое или второе.SaveOrUpdateCopy
- это уже устаревший метод, который передMerge
импортом был объединен в NHibernate .Насколько я понимаю,
merge()
будет принимать объект , который не может быть связан с текущей сессией, и скопировать свое состояние (значение свойств и т.д.) к объекту , который является связанным с текущей сессией (с тем же значением PK / идентификатором, из курс).saveOrUpdate()
вызовет Save или Update в вашем сеансе на основе значения идентификатора данного объекта.источник
SaveOrUpdateCopy()
теперь устарела в NHibernate 3.1.Merge()
следует использовать вместо этого.источник
SaveOrUpdateCopy
что отмеченоObsolete
, а неSaveOrUpdate
. Кажется, существует большая путаница между этими двумя разными методами в этом вопросе и последующих ответах.** Update()**
: - если вы уверены, что сеанс не содержит уже постоянного экземпляра с тем же идентификатором, используйте обновление, чтобы сохранить данные в спящем режиме
** Merge()**
: -если вы хотите сохранить изменения в любое время, не зная о состоянии сеанса, используйте merge () в спящем режиме.
источник
Я нашел эту ссылку, которая довольно хорошо объясняет этот тип исключения:
Для меня сработало следующее:
cascade="merge"
SaveOrUpdate
дочерний / зависимый объект, прежде чем назначать его родительскому объекту.SaveOrUpdate
родительский объект.Однако у этого решения есть ограничения. т.е. вы должны позаботиться о сохранении вашего дочернего / зависимого объекта вместо того, чтобы позволить спящему режиму делать это за вас.
Если у кого-то есть лучшее решение, я бы хотел посмотреть.
источник
@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(); } } }
источник