В чем разница между persist() и save() в Hibernate?

Через документацию я могу найти только одно различие, которое генерирует метод сохранения, возвращает объект как сгенерированный идентификатор, но сохраняется. Это единственная цель для предоставления метода persist. Если да, то как это помогает программисту, потому что если он не намеревается использовать сгенерированный идентификатор, он может использовать сохранение и игнорировать возвращаемое значение.

Также пришел через этот поток в В чем преимущество persist() vs save() в Hibernate?. Значимый оператор, который я могу получить из этого потока, persist() также гарантирует, что он не будет выполнять оператор INSERT, если он вызывается за пределами границ транзакций, который сохраняет метод, но не уверен, как я должен его попробовать в моей программе, чтобы я мог получить реальную разницу?

Ответ 1

Я сделал небольшое тестирование, чтобы записать разницу между Save() и Persist().

Похоже, что оба эти метода ведут себя одинаково при работе с Transient Entity, но отличаются при работе с Detached Entity.

В приведенном ниже примере возьмите EmployeeVehicle как объект с PK как vehicleId, который является сгенерированным значением и именем транспортного средства как одно из его свойств.

Пример 1: Работа с переходным объектом

                 Session session = factory.openSession();
                 session.beginTransaction();
                 EmployeeVehicle entity = new EmployeeVehicle();
                    entity.setVehicleName("Honda");
                 session.save(entity);
                 // session.persist(entity);
                session.getTransaction().commit();
                session.close();

Результат: select nextval ('hibernate_sequence')//Это для генерируемого идентификатора транспортного средства: 36

insert into Employee_Vehicle ( Vehicle_Name, Vehicle_Id) values ( Honda, 36)

Repeat the same with using persist(entity) and will result the same with new Id ( say 37 , honda ) ;

Пример 2: Работа с отдельным объектом

// Session 1 
            // Get the previously saved Vehicle Entity 
           Session session = factory.openSession();
            session.beginTransaction();
            EmployeeVehicle entity = (EmployeeVehicle)session.get(EmployeeVehicle.class, 36);
           session.close();

           // Session 2
           // Here in Session 2 , vehicle entity obtained in previous session is a detached object and now we will try to save / persist it 
         (i) Using Save() to persist a detached object 
           Session session2 = factory.openSession();
            session2.beginTransaction();
                    entity.setVehicleName("Toyota");
            session2.save(entity);
            session2.getTransaction().commit();
            session2.close();

Результат. Возможно, вы ожидаете, что Автомобиль с идентификатором: 36, полученный на предыдущем сеансе, обновляется с именем "Тойота". Но происходит то, что новый объект сохраняется в БД с новым идентификатором, сгенерированным для и именем, как "Тойота"

         select nextval ('hibernate_sequence')
         insert into Employee_Vehicle ( Vehicle_Name, Vehicle_Id) values ( Toyota, 39)

         (ii) Using Persist()  to persist a detached object 

            // Session 1 
            Session session = factory.openSession();
    session.beginTransaction();
    EmployeeVehicle entity = EmployeeVehicle)session.get(EmployeeVehicle.class, 36);
    session.close();

//Сессия 2 // Здесь, в Сессии 2, объект транспортного средства, полученный в предыдущем сеансе, является отдельным объектом, и теперь мы попытаемся сохранить/сохранить его (i) Использование persist() для сохранения отдельного объекта

            Session session2 = factory.openSession();
    session2.beginTransaction();
            entity.setVehicleName("Toyota");
    session2.persist(entity);
    session2.getTransaction().commit();
    session2.close();

Результат: Исключение выбрано: удаленный объект передан для сохранения

Итак, всегда лучше использовать Persist(), а не Save(), поскольку сохранение должно быть тщательно использовано при работе с сеансом и транкацией.

Ответ 2

  • Тип возврата: обе функции ВСТАВЛЯТЬ записи в базу данных, но тип возвращаемого значения метода persist() недействителен, в то время как тип возврата метода save() - это значение идентификатора первичного ключа, которое генерируется спящим режимом.

  • Идентификатор: метод persist() не гарантирует, что значение идентификатора будет немедленно присвоено постоянному экземпляру, назначение может произойти во время очистки.

  • Границы транзакций. Мы можем вызывать метод persist() только внутри транзакции, поэтому он безопасен и заботится о любых каскадных объектах. метод save() может вызывать внутри или за пределами транзакции.

  • Контекст: методы persist() добавляют объект сущности в постоянный контекст и отслеживают дальнейшие изменения. Любые дальнейшие изменения сохраняются во время совершения транзакции, например, persist.

метод finally persist() лучше, чем save().

examples

Ответ 3

save() возвращает идентификатор, и если для получения идентификатора должен быть выполнен INSERT, этот INSERT происходит немедленно, независимо от того, находитесь ли вы внутри или вне транзакции. Это не хорошо в длительной беседе с расширенным контекстом Session/persistence.

persist() используется для переходных объектов. Это делает переходный экземпляр постоянным. Тем не менее, это не гарантирует, что значение идентификатора будет немедленно назначено на постоянный экземпляр, назначение может произойти во время сброса. Это также гарантирует, что он не будет выполнять оператор INSERT, если он вызывается за пределами границ транзакции. Это полезно при длительных беседах с расширенным контекстом Session/persistence.

Ответ 4

Persist():

  • Это метод void и не гарантирует, что значение идентификатора присваивается экземпляру постоянства после INSERT. назначение может происходят во время промывки.
  • Он не будет выполнен, если его вызов из внешних транзакций границы.
  • Это будет полезно для длительных бесед с расширенным контекстом сеанса/персистентности.

Save():

  • Он вернет идентификатор после выполнения INSERT.
  • Он будет выполнен даже вне границ транзакции.
  • Это не полезно для длительных разговоров.

Ответ 5

public class TestSave {

public static void main(String[] args) {

    Session session= HibernateUtil.getSessionFactory().openSession();
    Person person= (Person) session.get(Person.class, 1);
    System.out.println(person.getName());
    session.close();

    Session session1= HibernateUtil.getSessionFactory().openSession();
    session1.beginTransaction();

    person.setName("person saved with Persist");
    session1.getTransaction().commit();
    System.out.println(session1.save(person));

    //session1.persist(person);
    session1.flush();

    session1.close();

}
}

Разница между Save и persist, Save execute вне транзакции. Выполните вышеуказанный код и проверьте консоль System.out.println(session1.save(person)) вернется с идентификатором и выполнит его снова, он увеличит ваш идентификатор. Теперь, если вы попытаетесь сохранить другую запись в таблице Person в базе данных с приведенным ниже кодом и обновите таблицу данных и проверьте столбец id в базе данных. Его значение будет увеличено.

public class TestMain {
  public static void main(String[] args) {
    Person person = new Person();
    saveEntity(person);
 }
private static void saveEntity(Person person) {
person.setId(1);
 person.setName("Concretepage1");
 Session session = HibernateUtil.getSessionFactory().openSession();
 session.beginTransaction();
 session.save(person);
 session.getTransaction().commit();
 session.close();
}

Если мы попытаемся сохранить данные за пределами границ транзакции, это даст исключение.

Ответ 6

Метод save() делает операцию вставки обычно внешней транзакции

public class HibernateSaveExample {

    public static void main(String[] args) {

        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
        Session session = sessionFactory.openSession();
        Student student = new Student("javabycode.com", new Date(), "USA", "1234569");
        Long studentId = (Long) session.save(student);
        System.out.println(" Identifier : " + studentId);
        System.out.println(" Successfully saved");

        Session session2 = sessionFactory.openSession();
        Transaction trans = session2.beginTransaction();

        Student student2 = new Student("javabycode.com", new Date(), "USA", "1234569");
        Long studentId2 = (Long) session2.save(student2);
        trans.commit();
        System.out.println(" Identifier : " + studentId2);
        System.out.println(" Successfully saved");

        sessionFactory.close();
    }

}

и метод persist() не может этого сделать.

И еще одно отличие метода сохранения и сохранения в Hibernate: persist поддерживается JPA, а сохранение поддерживается только Hibernate.

Из учебника Разница между методом сохранения и сохранения в Hibernate