Quel est l'avantage de persist() vs save() en hibernation?

quelqu'un peut-il me dire quel est l'avantage de persist() vs save() en hibernation?

141
demandé sur Andrew Tobilko 2011-05-03 01:27:54

10 réponses

à Partir de ce post sur le forum

persist() est bien défini. Il fait un instance transitoire persistante. Toutefois, cela ne garantit pas que l' identificateur de valeur sera attribuée à l'instance persistante immédiatement, la cession pourrait arriver à rincer temps. La spécification de ne pas dire qu', qui est le problème que j'ai avec persist() .

persist() garantit également qu'il ne pas exécuter une instruction INSERT si elle est appelé en dehors de la transaction frontière. Ceci est utile dans des conversations de longue date avec un Séance prolongée/contexte de persistance.

Une méthode comme persist() est nécessaire.

save() ne garantit pas le même, il retourne un identifiant, et si un INSERT doit être exécuté pour obtenir le identifiant (exemple: "identité" générateur, pas "séquence"), cet INSERT se produit immédiatement, peu importe si vous êtes à l'intérieur ou à l'extérieur d'une transaction. Ce n'est pas bon dans une longue conversation avec une longue Session/contexte de persistance.

135
répondu Bala R 2016-09-22 18:27:16

j'ai fait de bonnes recherches sur le save() vs persist() y compris l'exécuter sur ma machine locale plusieurs fois. Toutes les explications sont confuses et ne sont pas correctes. J'ai comparé le save() et le persist() ci-dessous après après une recherche approfondie.

Save()

  1. renvoie l'Id généré après enregistrement. Son type de retour Serializable .
  2. sauve la valeur au DB immédiatement et garde la trace de la entité jusqu'à la fin de la session(j'ai essayé de changer les valeurs de l'entité en dehors de la transaction, cela ne montre aucun effet lorsque la session s'engage)
  3. enregistrez les changements à la PD en dehors de l'opération.
  4. attribue l'id généré à l'entité que vous persistez
  5. Session.save() pour un décollement de l'objet va créer une nouvelle ligne dans la table.

Persist()

  1. ne renvoie pas l'Id généré après enregistrement. Son type de retour vide.
  2. sauve la valeur à DB immédiatement et garde la trace de l'entité jusqu'à la fin de la session.(J'ai essayé de changer les valeurs de l'entité en dehors de la transaction, cela n'a pas d'effet lorsque la session s'engage)
  3. Le code
  4. ne permet pas de sauvegarder les modifications apportées au PB en dehors de l'opération.
  5. assigne le generated id à l'entité que vous
  6. session.persist() pour un objet détaché lancera PersistentObjectException comme il est interdit.

tous ceux-ci sont essayés/testés sur Hibernate v4.0.1 .

51
répondu Zeus 2018-08-24 09:41:10

j'ai fait quelques essais simulés pour enregistrer la différence entre save() et persist() .

ressemble à ces deux méthodes se comportent de la même façon lorsqu'il s'agit d'entité transitoire, mais diffèrent lorsqu'il s'agit d'entité détachée.

pour l'exemple ci-dessous, prendre EmployeeVehicle comme une entité avec PK comme vehicleId qui est une valeur générée et vehicleName comme l'une de ses propriétés.

exemple 1: Transitoire Objet

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 obtenez un objet déjà persisté et enregistrez-le

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 la même chose en utilisant persist(entity) et vous obtiendrez le même résultat avec une nouvelle identification (disons 37, honda);

exemple 2: concernant 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 attendre le véhicule avec id : 36 obtenu dans la session précédente est mis à jour avec le nom comme "Toyota" . Mais ce qui se passe, c'est qu'une nouvelle entité est sauvée dans le DB avec un nouvel Id généré pour et nom comme "Toyota"

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

à l'Aide de persister à persister détaché de l'entité

// (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 soin lorsqu'il s'agit d'un objet transitoire .

Remarque importante: dans l'exemple ci-dessus , le pk de l'entité du véhicule est une valeur générée , donc lorsqu'on utilise save() pour persister une entité détachée , hibernate génère un nouveau id pour persister . Cependant, si ce pk n'est pas une valeur générée, il en résulte une exception indiquant que la clé a été violée.

22
répondu Deivanayagam Senthil 2014-12-15 18:06:06

Cette question a quelques bonnes réponses sur les différentes méthodes de persistance dans Hibernate. Pour répondre directement à votre question, avec save () l'instruction insert est exécutée immédiatement quel que soit l'état de la transaction. Il renvoie la touche insérée pour que vous puissiez faire quelque chose comme ceci:

long newKey = session.save(myObj);

utilisez save() si vous avez besoin d'un identifiant assigné à l'instance persistante immédiatement.

avec persist (), le insert statement est exécuté dans une transaction, pas nécessairement immédiatement. C'est préférable dans la plupart des cas.

utilisez persist() si vous n'avez pas besoin que l'insertion se produise hors séquence avec le mouvement et que vous n'avez pas besoin que la clé insérée soit retournée.

11
répondu CFL_Jeff 2017-05-23 11:54:58

save()- comme le suggère le nom de la méthode, hibernate save() peut être utilisé pour sauvegarder entity to database. Nous pouvons appeler cette méthode en dehors d'une transaction. Si nous l'utilisons sans transaction et que nous avons une cascade entre les entités, alors seule l'entité primaire est sauvegardée à moins que nous ne vidons la session.

persist () - Hibernate persist est similaire à save (with transaction) et ajoute l'objet entité au contexte persistant, de sorte que tout autre changement est suivi. Si l' les propriétés de l'objet sont modifiées avant que la transaction soit engagée ou que la session soit vidée, elle sera également sauvegardée dans la base de données. De plus, nous pouvons utiliser la méthode persist() uniquement à l'intérieur des limites d'une transaction, donc elle est sûre et prend soin de tous les objets en cascade. Enfin, persist ne renvoie rien, nous devons donc utiliser l'objet persist pour obtenir la valeur de l'identifiant généré.

5
répondu Rohit Goyal 2015-04-20 20:16:37

Voici les différences qui vous aident à obtenir l'avantage de persist and save méthode:

  • la première différence entre save et persist est le type de retour. Le type de retour de la méthode persist est vide tandis que le type de retour de save

    méthode est objet sérialisable.
  • la méthode persist() ne garantit pas que la valeur d'identification être attribué à l'état persistant immédiatement, la cession peut arriver à fleur du temps.

  • la méthode persist() n'exécute pas une requête insert si elle est appelée à l'extérieur des limites des transactions. Alors, la méthode save() retourne un identifiant de sorte qu'une requête insert soit exécutée immédiatement pour obtenir l'identificateur, peu importe si il sont à l'intérieur ou à l'extérieur d'un transaction.

  • la méthode de la persistance est appelée à l'extérieur des limites de la transaction, elle est utile dans conversations de longue durée avec une Session prolongée cadre. D'autre part enregistrer méthode n'est pas bon dans une longue conversation avec un contexte de Session étendu.

  • Cinquième de la différence entre enregistrer et de persister méthode en veille prolongée: persist est supporté par JPA, alors que save n'est supporté que par Hiberner.

vous pouvez voir l'exemple de travail complet de la poste différence entre sauver et méthode de la persistance en hibernation

5
répondu David Pham 2016-12-15 03:03:11

Voici la différence:

  1. enregistrer:

    1. renvoie l'id/l'identifiant lorsque l'objet est sauvegardé dans la base de données.
    2. sauvera aussi quand l'objet est essayé de faire la même chose en ouvrant une nouvelle session après qu'il soit détaché.
  2. Persistent:

    1. retournera nul lorsque l'objet est sauvé à la base de données.
    2. lancera PersistentObjectException lorsqu'on tentera de sauver l'objet détaché à travers une nouvelle session.
4
répondu Mohammed Amen 2017-01-28 15:48:46

en fait, la différence entre les méthodes hibernate save() et persist() dépend de la classe de générateur que nous utilisons.

Si notre classe generator est assignée, alors il n'y a pas de différence entre les méthodes save() et persist (). Parce que générateur " assigné’ signifie, en tant que programmeur, nous avons besoin de donner la valeur clé primaire pour enregistrer dans la base de données droit [ J'espère que vous connaissez ce concept de générateurs ] Dans le cas d'autres que la classe de générateur assignée, supposons que notre classe de générateur nom est incrément signifie hibernate il Auto assignera la valeur de l'id de la clé primaire dans la base de données droite [autre que le générateur assigné, hibernate seulement utilisé pour prendre soin de la valeur de l'id de la clé primaire se rappeler], donc dans ce cas si nous appelons save () ou persist () méthode, alors il insérera l'enregistrement dans la base de données normalement

Mais la chose entendue est, la méthode save() peut retourner cette valeur d'id clé primaire qui est générée par hibernate et nous pouvons la voir par

long s = session.enregistrer(k);

Dans ce même cas, persist() ne donnera jamais aucune valeur au client, return void.

persist () garantit également qu'il n'exécutera pas une instruction INSERT si elle est appelée en dehors des limites de la transaction.

où As Save () INSERT se produit immédiatement, peu importe si vous êtes à l'intérieur ou à l'extérieur d'une transaction.

2
répondu Hari Krishna 2014-05-30 11:48:16

règle de base dit que:

pour les entités avec identifiant généré:

save (): renvoie immédiatement l'identifiant d'une entité en plus de rendre l'objet persistant. Si une requête d'insertion est déclenché immédiatement.

persist (): renvoie l'objet persistant. Il n'a aucune contrainte de retourner l'identifiant immédiatement, donc il ne garantit pas que insert sera lancé immédiatement. Il peut mettre le feu à un insérer immédiatement, mais il n'est pas garanti. Dans certains cas, la requête peut être lancée immédiatement alors que dans d'autres elle peut être lancée au moment de la sortie de la session.

pour les entités ayant un identificateur attribué :

save (): renvoie immédiatement l'identifiant d'une entité. Puisque l'identifiant est déjà assigné à entity avant d'appeler save, insert n'est donc pas lancé immédiatement. Il est lancé à l'Heure de la sortie de la session.

persist() : la même que pour enregistrer. Il aussi insérez le feu au moment de la chasse d'eau.

supposons que nous ayons une entité qui utilise un identifiant généré comme suit:

@Entity
@Table(name="USER_DETAILS")
public class UserDetails {
    @Id
    @Column(name = "USER_ID")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int userId;

    @Column(name = "USER_NAME")
    private String userName;

    public int getUserId() {
        return userId;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
}

save ():

    Session session = sessionFactory.openSession();
    session.beginTransaction();
    UserDetails user = new UserDetails();
    user.setUserName("Gaurav");
    session.save(user); // Query is fired immediately as this statement is executed.
    session.getTransaction().commit();
    session.close();

persist ():

    Session session = sessionFactory.openSession();
    session.beginTransaction();
    UserDetails user = new UserDetails();
    user.setUserName("Gaurav");
    session.save(user); // Query is not guaranteed to be fired immediately. It may get fired here.
    session.getTransaction().commit(); // If it not executed in last statement then It is fired here.
    session.close();

supposons maintenant que nous ayons la même entité définie comme suit sans que le champ id ait généré l'annotation, c'est-à-dire que L'ID sera assigné manuellement.

@Entity
@Table(name="USER_DETAILS")
public class UserDetails {
    @Id
    @Column(name = "USER_ID")
    private int userId;

    @Column(name = "USER_NAME")
    private String userName;

    public int getUserId() {
        return userId;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
}

pour save ():

Session session = sessionFactory.openSession();
session.beginTransaction();
UserDetails user = new UserDetails();
user.setUserId(1);
user.setUserName("Gaurav");
session.save(user); // Query is not fired here since id for object being referred by user is already available. No query need to be fired to find it. Data for user now available in first level cache but not in db.
session.getTransaction().commit();// Query will be fired at this point and data for user will now also be available in DB
session.close();

pour persist ():

Session session = sessionFactory.openSession();
session.beginTransaction();
UserDetails user = new UserDetails();
user.setUserId(1);
user.setUserName("Gaurav");
session.persist(user); // Query is not fired here.Object is made persistent. Data for user now available in first level cache but not in db.
session.getTransaction().commit();// Query will be fired at this point and data for user will now also be available in DB
session.close();

Le cas ci-dessus était vrai lors de l'enregistrer ou de persister ont été appelés dans une transaction.

les autres points de différence entre save et persist sont:

  1. save() peut être appelé en dehors d'une transaction. Si l'identifiant assigné est utilisé, puisque l'id est déjà disponible, Aucune requête insert n'est immédiatement lancée. La requête est seulement lancée quand la session est rincée.

  2. si l'identificateur généré est utilisé , alors puisque l'id doit être généré, insert est immédiatement déclenché. Mais il ne sauve que l'entité principale. Si l'entité a des entités en cascade, celles-ci ne seront pas sauvegardées dans db à ce point. Ils seront sauvegardés lorsque la session sera vidée.

  3. si persist () est à l'extérieur d'une transaction, alors insert est déclenché uniquement lorsque la session est purgée peu importe le type d'identificateur (généré ou assigné) utilisé.

  4. si save est appelé sur un objet persistant, alors l'entité est sauvée en utilisant update query.

1
répondu Gaurav Kumar 2015-01-01 15:53:07

Il a complètement répondu sur la base de "générateur" de type ID, tandis que le stockage de n'importe quelle entité. Si la valeur pour generator est "assignée" ce qui signifie que vous fournissez L'ID. Puis il ne fait pas de différence en hibernation pour sauver ou persister. Vous pouvez aller avec n'importe quelle méthode que vous voulez. Si la valeur n'est pas" assignée " et que vous utilisez save (), alors vous obtiendrez ID comme retour à partir de l'opération save ().

une autre vérification consiste à vérifier si vous effectuez l'opération en dehors de la limite de transaction ou non. Parce persist () appartient à JPA tandis que save () est en hibernation. Ainsi, l'utilisation de persist () en dehors des limites de transaction ne permettra pas de le faire et de jeter l'exception liée à persistant. alors qu'avec save() aucune restriction de ce genre et on peut aller avec la transaction DB par save () en dehors de la limite de la transaction.

1
répondu Neeraj 2018-07-25 11:48:16