Възможни опции за състояние на обект
Както може би сте забелязали, когато обект е прикачен към Hibernate, състоянието му се нарича Persistent or Managed . Колко правилно? Постоянно or управлявано?
Възможно е и така, и така. Според спецификацията на JPA обектът има състояние Persist, а според спецификацията Hibernate състоянието му се нарича Managed.
В Hibernate работата с базата данни се извършва чрез обект от тип org.hibernate.Session . Според JPA класът трябва да се нарича javax.persistence.EntityManager. Това всъщност не е голям проблем, тъй като и двата типа са интерфейси.
Интерфейсът org.hibernate.Session се декларира по следния начин:
interface Session extends java.lang.AutoCloseable, javax.persistence.EntityManager, HibernateEntityManager, QueryProducer, java.io.Serializable, SharedSessionContract {
}
Следователно интерфейсът на сесията има всички методи, които са в интерфейса на EntityManager . Но той също има свой собствен, който е наследил от по-ранните версии на Hibernate, когато все още нямаше JPA спецификация.
Цялата тази ситуация е описана по следния начин:
![](https://cdn.codegym.cc/images/article/c4cc3931-5115-471e-aec1-812c863f7c4a/1024.jpeg)
Нека да разгледаме всички методи, които интерфейсът на сесията има, Howто и нюансите на тяхната работа.
Нюансите на метода persist().
Когато записвате обект в базата данни, трябва да запомните две неща.
Първо, запазването на обекта в крайна сметка ще доведе до изпълнението на една от SQL командите: INSERT or UPDATE. Второ, тези действия няма да се появят веднага след извикването на метода на обектасесия, но само след приключване на сделката.
Нека разгледаме една проста ситуация, например, имате потребителски клас :
@Entity
public class User {
@Id
@GeneratedValue
public Integer id;
@Columnt(name=”user_name”)
public String name;
}
Нека запазим неговия обект в базата данни с помощта на метода persist() .
User user = new User();
user.setName("Kolyan");
session.persist(user);
Целта на този метод е да запише нов обект в базата данни. Ако все още няма такъв обект, той ще бъде добавен към базата данни чрез извикване на метода INSERT SQL .
Ако обектът вече е в базата данни, тогава нищо няма да се случи. Възможен е обаче и трети случай - опит за записване на обект със статус Detached в базата данни. В този случай ще бъде хвърлено изключение. Пример:
User user = new User();
user.setName("Kolyan");
session.persist(user);
session.evict(user); // detach the object from the session
session.persist(user); // a PersistenceException will be thrown here!
Нюансите на метода save().
Методът save() е наследен от текущия Hibernate от предишните му версии. В основата си той е много подобен на метода persist() , също така добавя нов запис към tableта с помощта на метода INSERT. Той обаче има няколко интересни нюанса.
Първо, този метод връща стойност - новия идентификатор на обекта . Както вече знаете, обектите обикновено нямат идентификатор преди да бъдат добавени към базата данни и той вече е присвоен от базата данни. И така, методът save() на обекта на сесията връща идентификатора, който е присвоен на запазения обект.
важно! Според спецификацията на Hibernate ID, той може да бъде всеки сериализиращ се обект, а не само число. Може да бъде низ, число, enum, нещо общо, което може да бъде поставено изцяло в една колона на table в базата данни.
Методът save() има сериализиран тип резултат, така че неговият резултат трябва да бъде преобразуван в правилния тип:
User user = new User();
user.setName("Kolyan");
Integer id = (Integer) session.save(user);
Освен това методът save() има различно поведение в случай на състояние Detached на обекта. Той счита такъв обект за нов и просто добавя друг запис:
User user = new User();
user.setName("Kolyan");
Integer id = (Integer) session.save(user);
session.evict(user); // detach the object from the session
Integer id2 = (Integer) session.save(user);
Променливите id и id2 ще бъдат различни. Два записа ще бъдат добавени към tableта в базата данни, по един за всяка операция save() .