Разница между обновлением Hibernate по Session.update и HibernateTemplate.merge - PullRequest
2 голосов
/ 28 марта 2011

Я видел типы операций обновления: во-первых:

    getHibernateTemplate().execute(new HibernateCallback() {
        public Object doInHibernate(Session session) {  
            session.flush();
            session.setCacheMode(CacheMode.IGNORE);
            SomeObject ss = (SomeObject) session.get(SomeObject.class, id);
            long next = ss.getAndIncrement();
            session.update(ss);
            session.flush();
            return null;
        }
    });

и во-вторых

    SomeObject ss = loadSomeObject(); 
    long next = ss.getAndIncrement();
    getHibernateTemplate.merge(ss);

Эти два метода делают то же самое.Я хочу знать, какой из них лучше и безопаснее и почему.Спасибо.

Ответы [ 6 ]

13 голосов
/ 28 марта 2011

В первой операции объект ss имеет значение , прикрепленное к сеансу.где, как и во второй операции, его отсоединяется .Так что если у вас есть прикрепленные объекты, вы можете использовать обновление.Если у вас есть отсоединенные объекты, используйте команду слияния, которая сначала присоединяет объект к сеансу, а затем сделает обновление .

РЕДАКТИРОВАТЬ: для вашей информации о прикрепленных (постоянных) и отсоединенные объекты:

Hibernate определяет и поддерживает следующие состояния объекта:

Transient - объект является временным, если его экземпляр был создан с использованием оператора new, иэто не связано с Hibernate Session.Он не имеет постоянного представления в базе данных, и значение идентификатора не было назначено.Временные экземпляры будут уничтожены сборщиком мусора, если приложение больше не будет содержать ссылку.Используйте сеанс Hibernate, чтобы сделать объект постоянным (и пусть Hibernate позаботится о операторах SQL, которые должны быть выполнены для этого перехода).

Persistent - постоянный экземпляр имеет представление вбаза данных и значение идентификатора.Возможно, он просто был сохранен или загружен, однако по определению он входит в область действия сеанса.Hibernate обнаружит любые изменения, внесенные в объект в постоянном состоянии, и синхронизирует состояние с базой данных после завершения единицы работы.Разработчики не выполняют ручные операторы UPDATE или операторы DELETE, когда объект должен быть временным.

Detached - отсоединенный экземпляр - это объект, который был постоянным, но его Session был закрыт,Разумеется, ссылка на объект все еще действительна, и отсоединенный экземпляр может даже измениться в этом состоянии.Отдельный экземпляр может быть снова присоединен к новому сеансу позднее, что делает его (и все модификации) снова постоянным.Эта функция позволяет модели программирования для длительных единиц работы, которые требуют времени на обдумывание пользователем.Мы называем их прикладными транзакциями, т. Е. Единицей работы с точки зрения пользователя.

7 голосов
/ 13 июня 2012

Что такое API без примеров кода?

SessionFactory sf =         ctx.getBean("hibernateSessionFactory",SessionFactory.class);
Session session = sf.openSession();
Transaction t = session.beginTransaction();
try {
   Session s2 = sf.openSession();
    Organization org = (Organization)s2.get(Organization.class,100624l);//1
    org.setOrgName("org");
    s2.close();//2
   Organization org1 =  (Organization)session.get(Organization.class,100624l);//3
    org.setOrgName("testOrg");
   org1.setOrgName("org");//a
    session.merge(org);//4
    System.out.println(org == org1);//b 
     t.commit();
} catch (HibernateException e) {
  t.rollback();
  throw e;
}finally{
      session.close();
 }
  1. 1-й экземпляр загружен и сделан постоянным.
  2. Экземпляр отсоединен.
  3. Другой экземплярзагружен
  4. В момент выполнения этой операции в сеансе есть 2 экземпляра одного и того же объекта (org и org1) - org отключен, а org1 является постоянным, если мы выполняем update () или saveOrUpdate () здесь мы получаем следующее исключение:

org.hibernate.NonUniqueObjectException: другой объект с тем же значением идентификатора уже был связан с сеансом: [com.spring.model.Organization # 100624]

а.Мы делаем слияние здесь, которое:

I.Объединяет состояние отсоединенного объекта + постоянного объекта.

II.В случае конфликта объект, который объединен, выигрывает, как в этом случае, сохраненное значение будет: testOrg

III.Если бы мы объединились на org1, мы бы получили org.

b.Это всегда будет возвращать false, что означает, что после слияния, org все еще находился в состоянии DETACHED

Я надеюсь, что diff.теперь ясно.

Сводка: saveOrUpdate () или update () сгенерируют исключение, если в сеансе есть 2 экземпляра одного и того же объекта (один отсоединенный и один постоянный)

merge () не сгенерирует исключение, но сохранит объект при объединении изменений.

3 голосов
/ 28 марта 2011

Вот отличное объяснение разницы .

Надеюсь, что поможет.

2 голосов
/ 26 июля 2014

Слияние следует за

Слияние имеет интеллект.Он имеет много предварительных проверок перед тем, как произойдет фактическое слияние (если требуется)

  1. , если объект временный, он просто запускает запрос INSERT, делает объект постоянным (присоединяется к сеансу)
  2. , еслиОбъект отсоединяется, запускает запрос на выборку, чтобы проверить, были ли данные изменены или нет, если модифицирован, запускает запрос UPDATE, в противном случае просто игнорируется задача слияния.

где as session.update

  1. throwsисключение, если объект временный.
  2. если объект отсоединен, он просто запускает запрос UPDATE независимо от изменений данных в объекте.

session.merge дороже, чем update

1 голос
/ 11 мая 2014

Основное различие заключается в следующем:

Merge() не касается сеансов, постоянных или отключенных ... оно будет обновляться без учета сеансов.

В случае update()он выдаст исключение типа org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session.

Это объясняется здесь хорошим примером:

http://www.java4developer.com/difference-between-update-and-merge-in-hibernate/

0 голосов
/ 20 апреля 2015

Оба метода update () и merge () в hibernate используются для преобразования объекта, находящегося в отключенном состоянии, в состояние персистентности. Но есть небольшая разница. Давайте посмотрим, какой метод будет использоваться в какой ситуации. Давайте рассмотрим пример

SessionFactory factory = cfg.buildSessionFactory();
Session session1 = factory.openSession();

Employee s1 = null;
Object o = session1.get(Employee.class, new Integer(101));
s1 = (Student)o;
session1.close();

s1.setSSN(97);

Session session2 = factory.openSession();
Employee s2 = null;
Object o1 = session2.get(Employee.class, new Integer(101));
s2 = (Student)o1;
Transaction tx=session2.beginTransaction();

session2.merge(s1);
SessionFactory factory = cfg.buildSessionFactory();
Session session1 = factory.openSession();

Employee s1 = null;
Object o = session1.get(Employee.class, new Integer(101));
s1 = (Employee)o;
session1.close();

s1.setMarks(97);

Session session2 = factory.openSession();
Employee s2 = null;
Object o1 = session2.get(Employee.class, new Integer(101));
s2 = (Employee)o1;
Transaction tx=session2.beginTransaction();

session2.merge(s1);

Надеюсь, что вы все ясно ..., на самом деле, методы обновления и слияния появятся, когда мы снова и снова загружаем один и тот же объект в базу данных, как описано выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...