174 votes

Quelle est la différence entre session.persist() et session.save() dans Hibernate ?

Quelqu'un peut-il me dire quel est l'avantage de persist() vs save() dans Hibernate ?

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.

6voto

Gaurav Kumar Points 494

La règle de base dit que :

Pour les Entités avec identifiant généré :

save() : Elle renvoie immédiatement l'identifiant d'une entité en plus de rendre l'objet persistant. Ainsi, une requête d'insertion est lancée immédiatement.

persist() : Elle retourne l'objet persistant. Elle n'est pas obligée de retourner l'identifiant immédiatement et ne garantit donc pas que l'insertion sera déclenchée immédiatement. Elle peut déclencher une insertion immédiatement mais ce n'est pas garanti. Dans certains cas, la requête peut être lancée immédiatement, tandis que dans d'autres, elle peut être lancée au moment de la purge de la session.

Pour les Entités avec identifiant attribué :

sauvegarder() : Elle renvoie immédiatement l'identifiant d'une entité. Comme l'identifiant est déjà attribué à l'entité avant l'appel de save, l'insertion n'est pas déclenchée immédiatement. Il est déclenché au moment de l'ouverture de la session.

persist() : même chose que save. Elle déclenche également l'insertion au moment de la purge.

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();

persistent() :

    Session session = sessionFactory.openSession();
    session.beginTransaction();
    UserDetails user = new UserDetails();
    user.setUserName("Gaurav");
    session.persist(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 une annotation générée, c'est-à-dire que l'ID sera attribué 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();

Les cas ci-dessus étaient vrais lorsque la sauvegarde ou la persistance étaient appelées à l'intérieur d'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'identifiant est déjà disponible, aucune requête d'insertion n'est immédiatement lancée. La requête n'est lancée que lorsque la session est vidée.

  2. Si l'identifiant généré est utilisé, alors comme l'identifiant doit être généré, l'insertion est immédiatement déclenchée. Mais il ne sauvegarde que l'entité primaire. Si l'entité possède des entités en cascade, celles-ci ne seront pas sauvegardées dans la base de données à ce stade. Elles seront sauvegardées lorsque la session sera vidée.

  3. Si persist() est en dehors d'une transaction, l'insertion n'est déclenchée que lorsque la session est vidée, quel que soit le type d'identifiant (généré ou attribué) utilisé.

  4. Si la sauvegarde est appelée sur un objet persistant, alors l'entité est sauvegardée en utilisant la requête de mise à jour.

6voto

Rohit Goyal Points 45

Save()- Comme le nom de la méthode le suggère, hibernate save() peut être utilisé pour enregistrer une entité dans la base de données. Nous pouvons invoquer cette méthode en dehors d'une transaction. Si nous l'utilisons sans transaction et que nous avons des entités en cascade, seule l'entité primaire sera sauvegardée, à moins que nous ne vidions la session.

persist()-Hibernate persist est similaire à save (avec transaction) et ajoute l'objet entité au contexte persistant, de sorte que toute modification ultérieure est suivie. Si les propriétés de l'objet sont modifiées avant que la transaction ne soit validée ou que la session ne soit vidée, elles seront également enregistrées dans la base de données. De plus, nous ne pouvons utiliser la méthode persist() que dans le cadre d'une transaction, ce qui est sûr et prend en charge les objets en cascade. Enfin, persist ne renvoie rien, nous devons donc utiliser l'objet persistant pour obtenir la valeur de l'identifiant généré.

5voto

Mohammed Amen Points 111

Voici la différence :

  1. sauver :

    1. retournera l'id/identifiant lorsque l'objet sera enregistré dans la base de données.
    2. sera également sauvegardé lorsqu'on tentera de faire de même en ouvrant une nouvelle session après avoir détaché l'objet.
  2. Persiste :

    1. retournera void lorsque l'objet sera enregistré dans la base de données.
    2. lèvera l'exception PersistentObjectException si l'on tente de sauvegarder l'objet détaché dans une nouvelle session.

0 votes

Pouvez-vous s'il vous plaît montrer un exemple avec un snippet. Ce serait utile.

2voto

Hari Krishna Points 91

En fait, la différence entre les méthodes hibernate save() et persist() dépend de la classe du générateur que nous utilisons.
Si notre classe de générateur est affectée, alors il n'y a pas de différence entre les méthodes save() et persist(). Parce que le générateur "assigné" signifie que, en tant que programmeur, nous devons donner la valeur de la clé primaire à sauvegarder dans la base de données [ J'espère que vous connaissez ce concept de générateur ]. Dans le cas d'une classe de générateur autre qu'assignée, supposons que le nom de notre classe de générateur soit Incrément, ce qui signifie qu'Hibernate lui-même assignera la valeur de la clé primaire dans la base de données [autre que le générateur assigné, Hibernate ne s'occupe que de la valeur de la clé primaire], donc dans ce cas, si nous appelons la méthode save() ou persist(), l'enregistrement sera inséré dans la base de données normalement.
Mais ici, le fait est que la méthode save() peut retourner la valeur de l'identifiant de la clé primaire qui est générée par hibernate et nous pouvons le voir par
long s = session.save(k) ;
Dans ce même cas, persist() ne renverra jamais de valeur au client, de type void.
persist() garantit également qu'il n'exécutera pas une instruction INSERT s'il est appelé en dehors des limites de la transaction.
alors que dans save(), INSERT se produit immédiatement, peu importe que vous soyez à l'intérieur ou à l'extérieur d'une transaction.

0 votes

Qu'est-ce que la classe des générateurs ici ?

1voto

Neeraj Points 115

Il répond entièrement sur la base du type "générateur" dans l'ID lors du stockage de toute entité. Si la valeur du générateur est "assigned", cela signifie que vous fournissez l'ID. Alors il n'y a pas de différence dans Hibernate pour la sauvegarde ou la persistance. Vous pouvez utiliser la méthode que vous voulez. Si la valeur n'est pas "assignée" et que vous utilisez save(), vous obtiendrez l'ID en retour de l'opération save().

Un autre contrôle consiste à vérifier si vous effectuez l'opération en dehors de la limite de transaction ou non. Car persist() appartient à JPA alors que save() à Hibernate. Ainsi, l'utilisation de persist() en dehors des limites de la transaction ne permettra pas de le faire et lancera une exception liée au persistant. Alors qu'avec save(), il n'y a pas de restriction de ce type et on peut effectuer une transaction de la base de données par save() en dehors de la limite de la transaction.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X