Java hibernate update entity

Как изменить объект в Hibernate

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

Во-первых, это метод merge() , который обновляет информацию в базе на основе переданного объекта . При этом будет вызван SQL-запрос UPDATE. Пример:

 User user = new User(); user.setName("Колян"); session.save(user); session.evict(user); // отсоединяем объект от сессии user.setName("Маша"); User user2 = (User) session.merge(user); 

Тут есть несколько важных нюансов.

Во-первых, метод merge() возвращает результат – обновленный объект. Этот объект имеет состояние Persist и присоединен к объекту session. Объект передаваемый в метод merge() при этом не меняется.

Может показаться, что между user и user2 нет разницы, но это не так. В метод merge() можно передать POJO объект, а в качестве результата метод может вернуть proxy (зависит от настроек Hibernate). Поэтому просто запомни, что метод merge() не меняет передаваемый объект.

Во-вторых, если объект передаваемый в merge() имеет статус Transient (и у него нет ID), то для него создастся отдельная строчка в базе данных. Другими словами будет выполнена команда persist() .

В-третьих, если в метод merge() передать объект уже присоединенный к сессии (со статусом Persist), то ничего не произойдет – метод просто вернет этот же объект. Почему? А все потому, что при коммите транзакции данные и так запишутся в базу:

 User user = new User(); user.setName("Колян"); session.save(user); user.setName("Маша"); //меняем объект присоединенный к сессии session.close(); //в базу запишутся все измененные объекты 

Не нужно сохранять каждый раз объект после любых его изменений. Если этот объект в статусе Persist, то Hibernate все сделает сам. Если вы меняете объект, который “присоединен к базе”, то все его изменения будут записаны в базу.

Читайте также:  Css grid height 100

Нюансы работы метода update()

Также у Hibernate есть метод update() , который как и метод save() достался ему от предыдущих версий. С помощью этого метода можно только обновить данные уже сохраненного объекта. При этом будет вызван SQL-запрос UPDATE. Пример:

 User user = new User(); user.setName("Колян"); session.save(user); session.evict(user); // отсоединяем объект от сессии user.setName("Маша"); session.update(user); 

Этот метод ничего не возвращает и не меняет существующий объект.

Если вызвать этот метод для нового объекта, то просто кинется исключение:

 User user = new User(); user.setName("Колян"); session.update(user); //тут кинется исключение 

Метод saveOrUpdate()

До появления JPA функцию метода persist() выполнял метод saveOrUpdate() . Его задачей было обновить в базе информацию по существующему объекту, а если такового нет, то создать его. Его почти всегда используют вместо методов save() и update() .

В отличии от метода update() , он может менять передаваемый ему объект. Например, установить ему ID, который был присвоен при сохранении в базу данных. Пример:

 User user = new User(); user.setName("Колян"); session.saveOrUpdate(user); //объект будет записан в базу 
  • если у передаваемого объекта установлен ID, то вызывается SQL-метод UPDATE
  • если у передаваемого объекта ID не установлен, то вызывается SQL-метод INSERT

Источник

Hibernate save(), update() and saveOrUpdate()

Learn the different methods for persisting and updating the entity states in the database using Hibernate Session APIs to use save() , update() and saveOrUpdate() methods under different usecases.

Starting Hibernate 6.0, all save(), update() and saveOrUpdate() methods have been marked deprecated in favor of Jakarta persistence API provided persist() and merge() methods.

1. Entity Lifecycle States

A JPA or Hibernate entity can be in one of the following four states:

  • Transient (New)
  • Managed (Persistent)
  • Detached (Not associated with any Session)
  • Removed (Deleted)

The Hibernate Session provides state transition methods like save , saveOrUpdate and update apart from methods implemented from JPA specs, for example, persist(), merge() and remove().

The save() method is used make a TRANSIENT entity PERSISTENT by associating it with either an org.hibernate.Session . Before persisting the entity, it assigns a generated identifier to the ID field.

The save() method returns the generated identifier so it has to immediately execute the SQL INSERT statement (it does not matter if we are inside or outside of a transaction) because identifiers are generated by the database during the INSERT query execution only.

Note that if we call save() outside the transaction then associated entities may not be inserted immediately because save() has to return the generated identifier only for the main entity. This can cause data inconsistency if we forget to flush the changes or some application error happens.

EmployeeEntity employee = new EmployeeEntity(); employee.setEmail("demo-user@email.com"); employee.setFirstName("demo"); employee.setLastName("user"); Long >This will execute the SQL INSERT statement.
Hibernate: insert into Employee (ID, email, firstName, lastName) values (default, ?, ?, ?)

2.2. With Persistent Entity

For PERSISTENT entities, save() works as update() method and executes UPDATE SQL queries.

Long >Check out that the second statement is UPDATE query.
Hibernate: insert into Employee (ID, email, firstName, lastName) values (default, ?, ?, ?) Hibernate: update Employee set lastName=? where aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16">

A detached entity already has the identifier associated with it so the behavior of the save() method depends on the ID generation strategy when executing the INSERT query.

  • If the strategy is GenerationType.SEQUENCE then a new identifier will be generated and a duplicate record will be inserted into the database.
  • If the strategy is GenerationType.IDENTITY then we will get ConstraintViolationException for duplicate primary key violation.

The update() is pretty much a simpler method.

  • It executes the SQL UPDATE query for PERSISTENT entities.
  • It throws TransientObjectException if there is no identifier associated (transient entity).
EmployeeEntity emp = new EmployeeEntity(); emp.setEmail("demo-user@mail.com"); emp.setFirstName("demo"); emp.setLastName("user"); //Transient entity session.update(emp);

It will throw an exception.

org.hibernate.TransientObjectException: The given object has a null identifier: com.howtodoinjava.basics.entity.EmployeeEntity

To correctly update an entity, make it persistent first using save() or persist() methods.

EmployeeEntity emp = new EmployeeEntity(); emp.setEmail("demo-user@mail.com"); emp.setFirstName("demo"); emp.setLastName("user"); //Transient entity session.save(emp); emp.setLastName("userOne"); //Persistent entity session.update(emp);
Hibernate: insert into Employee (email, firstName, lastName, ID) values (?, ?, ?, ?) Hibernate: update Employee set lastName=? where aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16">

The saveOrUpdate(), as the name implies, works as either save() or update() on the basis of the ID field present in the entity or not. In most cases, it is the preferred method to save().

The saveOrUpdate() can be used with PERSISTENT as well as TRANSIENT entities both. Persistent entities will get updated, and transient entities will be inserted into the database.

EmployeeEntity emp = new EmployeeEntity(); emp.setEmail("demo-user@mail.com"); emp.setFirstName("demo"); emp.setLastName("user"); //Transient entity session.saveOrUpdate(emp); emp.setLastName("userOne"); //Persistent entity session.saveOrUpdate(emp);
Hibernate: insert into Employee (email, firstName, lastName, ID) values (?, ?, ?, ?) Hibernate: update Employee set lastName=? where aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16">
  • The save() method INSERTs an object in the database. It will persist the given transient instance, first assigning a generated identifier. It returns the id of the entity created.
  • The saveOrUpdate() calls either save() or update() on the basis of identifier exists or not. e.g if identifier does not exist, save() will be called or else update() will be called.

Источник

Updating an Entity with JPA

Persistence transition or state change when EntityManager’s find() called :

update-entity-lifecycle

Technologies Used in all of examples :

  • JPA 2.1
  • Hibernate 5.2.6
  • MySql 8.0
  • Maven 3
  • Spring Tool Suite (STS) 3.9.8
  • Java 1.8

Mapping Studen.java class

@Entity(name="STUDENT") public class Student < @Id @GeneratedValue(strategy=GenerationType.AUTO, generator="native") @GenericGenerator(name = "native", strategy = "native") @Column(name = "ID") private Long studentId; @Column(name = "FNAME") private String firstName; @Column(name = "LNAME") private String lastName; @Column(name = "CONTACT_NO") private String contactNo; // setters and getters

Updating Entity Code :

Following example demonstrates updating column value of Student table when a Student record already exist in DB.

public static void main( String[] args ) < EntityManagerFactory emf = null; EntityManager entityManager = null; EntityTransaction transaction = null; try< emf = Persistence.createEntityManagerFactory("jbd-pu"); entityManager = emf.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); /* When ever EntityManager's find() calls the state of Student instance will be "Persistent" */ Student student = entityManager.find(Student.class, 2L); /*If we are changing persistent State object values, * those are synchronized automatically with the database while committing the transaction.*/ student.setFirstName("Peter"); transaction.commit(); >catch(Exception e)< transaction.rollback(); >finally < entityManager.close(); emf.close(); >>
INFO - HHH000397: Using ASTQueryTranslatorFactory Hibernate: select student0_.ID as ID1_0_0_, student0_.CONTACT_NO as CONTACT_2_0_0_, student0_.FNAME as FNAME3_0_0_, student0_.LNAME as LNAME4_0_0_ from STUDENT student0_ where student0_.ID=? Hibernate: update STUDENT set CONTACT_NO=?, FNAME=?, LNAME=? where - HHH000030: Cleaning up connection pool [jdbc:mysql://localhost:3306/jpa_JBD]

To update detached entities to the database, use merge method.

Download Application – JPA-Entity-Update.zip (10 KB)

Источник

Оцените статью