209 votes

Quelles sont les différences entre les différentes méthodes d’épargne dans la mise en veille prolongée ?

Mise en veille prolongée a une poignée de méthodes qui, une manière ou une autre, prend votre objet et le met dans la base de données. Quelles sont les différences entre eux, quand utiliser qui, et pourquoi n’y a-t-il pas une seule méthode intelligente qui sait quand utiliser quoi ?

Les méthodes que j’ai identifiées à ce jour sont :

  • Save()
  • Update()
  • saveOrUpdate()
  • saveOrUpdateCopy()
  • Merge()
  • Persist()

121voto

Lee Theobald Points 2512

Voici ma compréhension des méthodes. Principalement, ce sont basées sur l' API mais comme je n'utilise pas la totalité de ceux-ci dans la pratique.

saveOrUpdate Appels d'enregistrer ou de mettre à jour en fonction de certains contrôles. E. g. si aucun identifiant n'existe, save est appelée. Sinon mise à jour est appelée.

enregistrer Persiste une entité. Va affecter un identifiant si l'un n'existe pas. Si on le fait, c'est essentiellement de faire une mise à jour. Retourne l'IDENTIFIANT généré de l'entité.

mise à jour Tente de conserver l'entité à l'aide d'un identifiant existant. Si aucun identifiant n'existe, je crois, une exception est levée.

saveOrUpdateCopy Elle est obsolète et ne devrait plus être utilisée. Au lieu de cela, il y a...

fusion Maintenant c'est là que ma connaissance commence à faiblir. La chose importante ici est la différence entre transitoire, détaché et persistant entités. Pour plus d'informations sur les états d'objet, prendre un coup d'oeil ici. Avec enregistrer et de mise à jour, vous êtes confronté à persistant des objets. Elles sont liées à une Session Hibernate sait ce qui a changé. Mais quand vous avez un transitoire de l'objet, il n'y a pas de session en cause. Dans ces cas, vous devez utiliser de fusion pour les mises à jour et persistent pendant saviing.

persistent Comme mentionné ci-dessus, il est employé sur des objets transitoires. Elle ne retourne l'IDENTIFIANT généré.

117voto

shevchik Points 6781
╔══════════════╦═══════════════════════════════╦════════════════════════════════╗
║    METHOD    ║            TRANSIENT          ║            DETACHED            ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║              ║       sets id if doesn't      ║   sets new id even if object   ║
║    save()    ║     exist, persists to db,    ║    already has it, persists    ║
║              ║    returns attached object    ║ to DB, returns attached object ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║              ║       sets id on object       ║             throws             ║
║   persist()  ║     persists object to DB     ║       PersistenceException     ║
║              ║                               ║                                ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║              ║                               ║                                ║
║   update()   ║           Exception           ║     persists and reattaches    ║
║              ║                               ║                                ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║              ║  copy the state of object in  ║    copy the state of obj in    ║
║    merge()   ║     DB, doesn't attach it,    ║      DB, doesn't attach it,    ║
║              ║    returns attached object    ║     returns attached object    ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║              ║                               ║                                ║
║saveOrUpdate()║           as save()           ║            as update()         ║
║              ║                               ║                                ║
╚══════════════╩═══════════════════════════════╩════════════════════════════════╝

70voto

jrudolph Points 3726
  • Voir les Hibernate Forum pour une explication des différences subtiles entre persistent et économisez. Il ressemble à la différence, c'est le temps de l'instruction INSERT est finalement exécuté. Depuis enregistrer renvoie l'identificateur de l'instruction INSERT doit être exécutée instantanément quel que soit l'état de la transaction (ce qui est généralement une mauvaise chose). Persister à ne pas exécuter toutes les déclarations à l'extérieur de la transaction juste pour affecter l'identificateur. Enregistrer/Persistent à la fois le travail sur les instances éphémères, c'est à dire les instances qui n'ont pas de numéro d'identification de encore et en tant que tels ne sont pas enregistrées dans la base de données.

  • Mise à jour et de Fusionner les deux travailler sur instances détachées, c'est à dire les instances qui ont une entrée correspondante dans la base de données mais qui ne sont pas actuellement fixé à (ou gérés par) une Session. La différence entre eux sont ce qui se passe à l'instance qui est passé à la fonction. mise à jour tente de remettre en place le cas, cela signifie qu'il y a peut être pas d'autre exemple de la persistance de l'entité attachée à la Session sinon une exception est levée. de fusion, cependant, seulement des copies de toutes les valeurs d'une instance persistante dans la Session (qui sera chargé si elle n'est pas actuellement chargée). L'entrée de l'objet n'est pas modifié. Afin de fusion est plus générale que la mise à jour, mais peut utiliser plus de ressources.

12voto

Manish Points 175

Ce lien qui explique en bonne manière :

http://www.stevideter.com/2008/12/07/saveorupdate-versus-merge-in-hibernate/

Nous avons tous les problèmes que l'on rencontre assez rarement que lorsque nous les voyons encore, nous savons que nous avons résolu ce problème, mais ne me souviens pas comment.

Le NonUniqueObjectException jeté lors de l'utilisation de Session.saveOrUpdate() en mode veille prolongée est l'un des miens. Je vais être en ajoutant de nouvelles fonctionnalités à une application complexe. Tous mes tests unitaires, beau travail. Puis dans les tests de l'INTERFACE utilisateur, en essayant de sauver un objet, je commence à être une exception avec le message "un objet différent avec le même identifiant de la valeur a déjà été associé à la session." Voici un exemple de code à partir de Java Persistance avec Hibernate.

            Session session = sessionFactory1.openSession();
            Transaction tx = session.beginTransaction();
            Item item = (Item) session.get(Item.class, new Long(1234));
            tx.commit();
            session.close(); // end of first session, item is detached

            item.getId(); // The database identity is "1234"
            item.setDescription("my new description");
            Session session2 = sessionFactory.openSession();
            Transaction tx2 = session2.beginTransaction();
            Item item2 = (Item) session2.get(Item.class, new Long(1234));
            session2.update(item); // Throws NonUniqueObjectException
            tx2.commit();
            session2.close();

Pour comprendre la cause de cette exception, il est important de comprendre des objets détachés et ce qui se passe lorsque vous appelez saveOrUpdate() (ou juste une mise à jour()) sur un décollement de l'objet.

Quand on ferme un individu Session Hibernate, les objets persistants avec qui nous travaillons détaché. Cela signifie que les données sont toujours dans l'application de la mémoire, mais Hibernate n'est plus responsable pour le suivi des modifications apportées aux objets.

Si nous modifions notre détaché de l'objet et souhaitez le mettre à jour, nous devons rattacher à l'objet. Pendant que le processus de rattachement, Hibernate va vérifier pour voir si il y a toutes les autres copies du même objet. S'il en trouve, il a à nous dire qu'il ne sait pas ce que le "réel" copie est plus. Peut-être d'autres modifications ont été apportées à ceux d'autres exemplaires que nous nous attendons à être sauvés, mais Hibernate ne les connaît pas, parce qu'il n'était pas de les gérer à l'époque.

Plutôt que l'exception peut-être de mauvaises données, Hibernate nous dit à propos de ce problème via la NonUniqueObjectException.

Alors que devons nous faire? Dans Hibernate 3, nous avons merge() (dans Hibernate 2, utilisez saveOrUpdateCopy()). Cette méthode force Hibernate pour copier des changements par rapport à d'autres instances détachées sur l'instance que vous souhaitez enregistrer, et regroupe donc toutes les modifications en mémoire avant de l'enregistrer.

        Session session = sessionFactory1.openSession();
        Transaction tx = session.beginTransaction();
        Item item = (Item) session.get(Item.class, new Long(1234));
        tx.commit();
        session.close(); // end of first session, item is detached

        item.getId(); // The database identity is "1234"
        item.setDescription("my new description");
        Session session2 = sessionFactory.openSession();
        Transaction tx2 = session2.beginTransaction();
        Item item2 = (Item) session2.get(Item.class, new Long(1234));
        Item item3 = session2.merge(item); // Success!
        tx2.commit();
        session2.close();

Il est important de noter que l'opération de fusion renvoie une référence à la nouvelle version mise à jour de l'instance. Ce n'est pas le rattachement de l'élément de la Session. Si vous testez par exemple l'égalité (item == item3), vous verrez qu'il renvoie false dans le cas présent. Vous aurez probablement envie de travailler avec item3 à partir de ce point.

Il est également important de noter que la JPA (Java Persistence API) n'ont pas de concept de détaché et remis en place les objets, et utilise l'EntityManager.persist() et l'EntityManager.merge().

J'ai trouvé que, en général, lors de l'utilisation d'Hibernate, saveOrUpdate() est généralement suffisant pour mes besoins. J'ai l'habitude de n'utiliser que de fusionner quand j'ai des objets qui peuvent avoir des références à des objets de même type. Plus récemment, la cause de l'exception était dans le code de validation que la référence n'est pas récursive. J'était en train de charger le même objet dans ma session, dans le cadre de la validation, de l'origine de l'erreur.

Où avez-vous rencontré ce problème? Avez-fusionner le travail pour vous ou avez-vous besoin d'une autre solution? Préférez-vous de toujours utiliser la fusion, ou si vous préférez utiliser seulement dans la mesure nécessaire pour des cas spécifiques

5voto

Hari Krishna Points 51

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

Si notre générateur de classe sera affectée, alors il n'y a pas de différence entre save() et persist() des méthodes. Parce que générateur de "attribuées" signifie, en tant que programmeur, nous avons besoin de donner la clé primaire de la valeur à enregistrer dans la base de données [ j'Espère que vous savez ce générateurs concept ] Dans les cas autres que ceux affectés générateur de classe, suppose que si notre générateur de nom de la classe est Incrément de moyens hibernate, il ne restera de lui attribuer l'id de clé primaire de la valeur dans la base de données [ autres que assigné générateur, hibernate seulement utilisé pour prendre soin de la clé primaire id valeur rappelez-vous ], dans ce cas, si nous appelons save() ou persist() méthode, puis il va insérer l'enregistrement dans la base de données normalement Mais entendre la chose est, save() méthode peut retourner que l'id de clé primaire de la valeur qui est généré par hibernate et nous pouvons le voir par

long s = session.save(k);

Dans cette même affaire, persist() ne sera jamais donner n'importe quelle valeur pour le client.

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