J’avais écrit avec succès mon premier exemple d’enfant maître avec l’hibernation. Après quelques jours, je l’ai repris et amélioré certaines bibliothèques. Je ne sais pas ce que je faisais mais je ne pourrais jamais le faire fonctionner à nouveau. Quelqu’un pourrait-il aider à comprendre ce qui ne va pas dans le code qui renvoie le message d’erreur suivant:
org.hibernate.PersistentObjectException: detached entity passed to persist: example.forms.InvoiceItem at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:127) at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:799) at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:791) .... (truncated)
mise en veille prolongée:
EDIT: InvoiceManager.java
class InvoiceManager { public Long save(Invoice theInvoice) throws RemoteException { Session session = HbmUtils.getSessionFactory().getCurrentSession(); Transaction tx = null; Long id = null; try { tx = session.beginTransaction(); session.persist(theInvoice); tx.commit(); id = theInvoice.getId(); } catch (RuntimeException e) { if (tx != null) tx.rollback(); e.printStackTrace(); throw new RemoteException("Invoice could not be saved"); } finally { if (session.isOpen()) session.close(); } return id; } public Invoice getInvoice(Long cid) throws RemoteException { Session session = HbmUtils.getSessionFactory().getCurrentSession(); Transaction tx = null; Invoice theInvoice = null; try { tx = session.beginTransaction(); Query q = session .createQuery( "from Invoice as invoice " + "left join fetch invoice.items as invoiceItems " + "where invoice.id = :id ") .setReadOnly(true); q.setParameter("id", cid); theInvoice = (Invoice) q.uniqueResult(); tx.commit(); } catch (RuntimeException e) { tx.rollback(); } finally { if (session.isOpen()) session.close(); } return theInvoice; } }
Facture.java
public class Invoice implements java.io.Serializable { private Long id; private Date invDate; private int customerId; private Set items; public Long getId() { return id; } public Date getInvDate() { return invDate; } public int getCustomerId() { return customerId; } public Set getItems() { return items; } void setId(Long id) { this.id = id; } void setInvDate(Date invDate) { this.invDate = invDate; } void setCustomerId(int customerId) { this.customerId = customerId; } void setItems(Set items) { this.items = items; } }
FactureItem.java
public class InvoiceItem implements java.io.Serializable { private Long itemId; private long productId; private Ssortingng packname; private int quantity; private double price; private Invoice invoice; public Long getItemId() { return itemId; } public long getProductId() { return productId; } public Ssortingng getPackname() { return packname; } public int getQuantity() { return quantity; } public double getPrice() { return price; } public Invoice getInvoice() { return invoice; } void setItemId(Long itemId) { this.itemId = itemId; } void setProductId(long productId) { this.productId = productId; } void setPackname(Ssortingng packname) { this.packname = packname; } void setQuantity(int quantity) { this.quantity = quantity; } void setPrice(double price) { this.price = price; } void setInvoice(Invoice invoice) { this.invoice = invoice; } }
EDIT: object JSON envoyé par le client:
{"id":null,"customerId":3,"invDate":"2005-06-07T04:00:00.000Z","items":[ {"itemId":1,"productId":1,"quantity":10,"price":100}, {"itemId":2,"productId":2,"quantity":20,"price":200}, {"itemId":3,"productId":3,"quantity":30,"price":300}]}
EDIT: Quelques détails:
J’ai essayé de sauvegarder la facture de deux manières:
Fabriqué manuellement object json mentionné ci-dessus et transmis à la nouvelle session du serveur. Dans ce cas, aucune activité n’a été effectuée avant d’appeler la méthode save, il ne doit donc y avoir aucune session ouverte sauf celle ouverte dans la méthode save
Chargement des données existantes à l’aide de la méthode getInvoice et transmission des mêmes données après suppression de la valeur de la clé. Je pense également que cela devrait fermer la session avant d’enregistrer, car la transaction est validée dans la méthode getInvoice.
Dans les deux cas, je reçois le même message d’erreur qui me force à croire que quelque chose ne va pas avec le fichier de configuration d’hibernation, les classes d’entités ou la méthode de sauvegarde.
S’il vous plaît laissez-moi savoir si je devrais fournir plus de détails
Vous n’avez pas fourni beaucoup de détails pertinents, donc je suppose que vous avez appelé getInvoice
, puis vous avez utilisé un object de résultat pour définir certaines valeurs et vous avez appelé à save
vos modifications d’object.
Cependant, l’opération persist
est destinée aux nouveaux objects transitoires et échoue si l’ID est déjà atsortingbué. Dans votre cas, vous souhaiterez probablement appeler saveOrUpdate
au lieu de persist
.
Vous pouvez trouver des discussions et des références ici “entité détachée passée pour persister l’erreur” avec le code JPA / EJB
Ici, vous avez utilisé natif et assigné une valeur à la clé primaire, en clé primaire native est généré automatiquement.
D’où le problème arrive.
Très probablement, le problème se situe en dehors du code que vous nous indiquez ici. Vous essayez de mettre à jour un object qui n’est pas associé à la session en cours. Si ce n’est pas la facture, alors c’est peut-être un InvoiceItem qui a déjà été conservé, obtenu à partir de la firebase database, maintenu en vie dans une sorte de session et vous essayez ensuite de le persister dans une nouvelle session. Ce n’est pas possible. En règle générale, ne laissez jamais vos objects persistants en vie entre les sessions.
La solution consiste, par exemple, à obtenir le graphe d’object entier à partir de la même session avec laquelle vous essayez de la conserver. Dans un environnement Web, cela signifierait:
Si vous continuez à avoir des problèmes, publiez une partie du code qui appelle votre service.