J'ai fait quelques tests simulés pour enregistrer la différence entre save()
y persist()
.
Il semble que ces deux méthodes se comportent de la même manière lorsqu'il s'agit d'une entité transitoire, mais diffèrent lorsqu'il s'agit d'une entité détachée.
Dans l'exemple ci-dessous, prenons EmployeeVehicle comme entité avec PK en tant que vehicleId
qui est une valeur générée et vehicleName
comme l'une de ses propriétés.
Exemple 1 : Traitement d'un objet transitoire
Session session = factory.openSession();
session.beginTransaction();
EmployeeVehicle entity = new EmployeeVehicle();
entity.setVehicleName("Honda");
session.save(entity);
// session.persist(entity);
session.getTransaction().commit();
session.close();
Résultat :
select nextval ('hibernate_sequence') // This is for vehicle Id generated : 36
insert into Employee_Vehicle ( Vehicle_Name, Vehicle_Id) values ( Honda, 36)
Notez que le résultat est le même lorsque vous récupérez un objet déjà persistant et que vous le sauvegardez.
EmployeeVehicle entity = (EmployeeVehicle)session.get(EmployeeVehicle.class, 36);
entity.setVehicleName("Toyota");
session.save(entity); -------> **instead of session.update(entity);**
// session.persist(entity);
Répétez l'opération en utilisant persist(entity)
et le résultat sera le même avec une nouvelle Id ( disons 37 , honda ) ;
Exemple 2 : Traitement d'un objet détaché
// 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();
Résultat : Vous pourriez vous attendre à ce que le véhicule avec l'id : 36 obtenu dans la session précédente soit mis à jour avec le nom "Toyota". Mais ce qui se passe, c'est qu'une nouvelle entité est sauvegardée dans la base de données avec le nouvel ID généré pour et le nom "Toyota".
select nextval ('hibernate_sequence')
insert into Employee_Vehicle ( Vehicle_Name, Vehicle_Id) values ( Toyota, 39)
Utilisation de persist pour persister une entité détachée
// (ii) Using Persist() to persist a detached
// Session 1
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
Session session2 = factory.openSession();
session2.beginTransaction();
entity.setVehicleName("Toyota");
session2.persist(entity);
session2.getTransaction().commit();
session2.close();
Résultat :
Exception being thrown : detached entity passed to persist
Ainsi, il est toujours préférable d'utiliser Persist() plutôt que Save() car Save doit être utilisé avec précaution lorsqu'il s'agit d'objets transitoires.
Note importante : Dans l'exemple ci-dessus, le pk de l'entité véhicule est une valeur générée, donc quand on utilise save() pour persister une entité détachée, Hibernate génère un nouvel id à persister. Cependant, si ce pk n'est pas une valeur générée, il en résulte une exception indiquant que la clé est violée.
10 votes
Voir aussi : Quel est l'avantage de load() par rapport à get() dans Hibernate ? stackoverflow.com/questions/5370482/
0 votes
C'est l'un des dernières réponses à ce jour par Vlad Mihalcea, l'auteur lui-même. Après avoir parcouru plusieurs anciens fils de discussion sur la documentation, la doc officielle et de nombreuses variantes sur Stack Overflow, voici l'une des réponses les mieux rassemblées avec des extraits. Ce site lien contient également les états du cycle de vie de l'entité, au cas où vous en auriez besoin.