Dupliquer une collection d'entités et de persister dans Hibernate/JPA
Je veux dupliquer une collection d'entités dans ma base de données.
J'ai récupérer la collection:
CategoryHistory chNew = new CategoryHistory();
CategoryHistory chLast = (CategoryHistory)em.createQuery("SELECT ch from CategoryHistory ch WHERE ch.date = MAX(date)").getSingleResult;
List<Category> categories = chLast.getCategories();
chNew.addCategories(categories)//Should be a copy of the categories: OneToMany
Maintenant, je veux dupliquer une liste des "catégories" et persister avec l'EntityManager.
Je suis en utilisant JPA/Hibernate.
Mise à JOUR
Après avoir su comment détacher mes entités, j'ai besoin de savoir ce que le détacher:
code actuel:
CategoryHistory chLast = (CategoryHistory)em.createQuery("SELECT ch from CategoryHistory ch WHERE ch.date=(SELECT MAX(date) from CategoryHistory)").getSingleResult();
Set<Category> categories =chLast.getCategories();
//detach
org.hibernate.Session session = ((org.hibernate.ejb.EntityManagerImpl) em.getDelegate()).getSession();
session.evict(chLast);//detaches also its child-entities?
//set the realations
chNew.setCategories(categories);
for (Category category : categories) {
category.setCategoryHistory(chNew);
}
//set now create date
chNew.setDate(Calendar.getInstance().getTime());
//persist
em.persist(chNew);
Cela jette un failed to lazily initialize a collection of role: entities.CategoryHistory.categories, no session or session was closed
exception.
Je pense qu'il veut un chargement différé des catégories de nouveau, puisque je les ai détachés. Que dois-je faire maintenant?
dans ce cas, qu'entendez-vous par "copie"? Et pourquoi ne pas ce travail pour vous?
OriginalL'auteur Michael Bavin | 2009-12-29
Vous devez vous connecter pour publier un commentaire.
Aaron Diguila de réponse est le chemin à parcourir ici, c'est à dire que vous devez
detach
votre cas, définissez la clé d'entreprise ànull
et puispersist
.Malheureusement, il n'existe aucun moyen de déconnecter un objet à partir de l'entité gestionnaire avec JPA 1.x (JPA 2.0 aura
EntityManager.detach(Object)
et résoudre ce problème). Donc, soit attendre JPA 2.x (pas une option je crois) ou l'utilisation de Hibernate sous-jacentSession
.Pour ce faire, vous pouvez lancer le délégué d'un EntityManager pour une Session Hibernate.
Bien sûr, cela ne fonctionne que si vous utilisez Hiberner comme un fournisseur de Persistance Java, parce que le délégué est la Session de l'API.
Ensuite, pour détacher votre objet:
Mise à JOUR: Selon Être prudent tout en utilisant l'EntityManager.getDelegate(), avec GlassFish on devrait utiliser effectivement (et probablement dans votre cas) :
Mais ce serait pas travail dans JBoss qui suggérer d'utiliser le code mentionné précédemment.
Même si je comprends que l'utilisation de
getDelegate()
fait JPA code non portable, je dois avouer que je ne m'attendais pas à la suite de l'appel de cette méthode à la mise en œuvre spécifique.UPDATE2: pour répondre À la mise à jour de la partie de la question, je ne suis pas sûr que vous avez chargé avec impatience les catégories. Ce n'est pas la meilleure façon de le faire, mais ce qui se passe si vous appelez
categories.get(0)
avant l'expulsion? Aussi, j'ai peut-être absent de cette partie mais, où avez-vous annuler la clé de catégories?En effet, mais 1. Aaron ne pas mentionner d'abord comment obtenir le
Session
2. tout en répondant, vous n'êtes pas informé par les commentaires de réponses donc je n'ai pas d'avis, il répondit que la partie 3. Je voulais mentionner que la JPA 2.0 n'ont ledetach()
méthode et Aaron ne l'a pas mentionné. Et à la fin, on dirait que vous allez de cette façon, au moins, un gars l'a trouvé utile.OriginalL'auteur Pascal Thivent
Vous devez vous détacher de vos instances de la session. Il y a trois façons de le faire:
Ensuite, vous devez modifier la clé d'entreprise (de sorte que les nouvelles instances seront de retour
false
lors de l'appel deequals()
avec un non modifié, par exemple). C'est l'étape importante: Sans elle, Hibernate va rattacher les instances à celles déjà existantes dans la base de données ou vous obtiendrez d'autres, des erreurs étranges.Après cela, vous pouvez enregistrer les nouvelles copies juste comme toute autre instance.
(Session)em.getDelegate ()
vous obtient la session en cours. L'EM n'a pas de méthode pour détacher des objets, vous pouvez uniquement supprimer (= supprimer).Serait-il travailler avec d'autres implémentations JPA? Juste par curiosité, parce que la méthode renvoie un Objet générique instance de type et ils ont dit que sa mise en œuvre spécifique.
Je ne trouve pas le détacher de la méthode sur un org.mise en veille prolongée.Session? Ou suis-je aveugle?hibernate.org/hib_docs/v3/api/org/hibernate/Session.html
Même, la Session s = ((Session)em.getDelegate()); jette: ClassCastException: org.mise en veille prolongée.ejb.EntityManagerImpl ne peut pas être lancé pour org.mise en veille prolongée.Session
OriginalL'auteur Aaron Digulla
Ok,
Depuis que je suis à l'aide de glassfish v3, et JPA2.0 est la finale, j'ai utilisé l'EntityManager.detach()
Étrangement ejb3-persistence.jar a été inclus dans ma lib, donc je m'avaient envoyé et utilisé javax.la persistance de la glassfish jar. Le détachement de la méthode est là, mais mon hibernate version n'a pas de mise en œuvre encore
Merci de ne pas poster des commentaires à votre question que de réponses. Modifier la question de la place.
ok je pensais que cela pourrait être une réponse pour les autres à l'aide d'une mise en œuvre de JPA 2.0 🙂
OriginalL'auteur Michael Bavin
BeanUtils.copyProperties(copy, orig)
Dans OpenJPA, supprimez manuellement le suivi de l'entité à l'aide d'Apache BeanUtils:
BeanUtils.setProperty(copy, "pcVersionInit", false);
Définir la clé primaire, à défaut/null.
Voir aussi: http://www.java-tutorial.ch/java-persistence-api/how-to-persist-duplicate-of-an-entity-with-openjpa
OriginalL'auteur Victor Lyuboslavsky