J’essaie d’exécuter ce code de base JPA / EJB:
public static void main(Ssortingng[] args){ UserBean user = new UserBean(); user.setId(1); user.setUserName("name1"); user.setPassword("passwd1"); em.persist(user); }
Je reçois cette erreur:
javax.ejb.EJBException: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.JPA.Database
Des idées?
Je recherche sur Internet et la raison pour laquelle j’ai trouvé était:
Cela a été causé par la façon dont vous avez créé les objects, c’est-à-dire si vous définissez explicitement la propriété ID. Suppression de l’affectation d’ID corrigée.
Mais je ne l’ai pas compris, que devrai-je modifier pour que le code fonctionne?
Disons que vous avez deux entités Album
et Photo
. L’album contient beaucoup de photos, donc c’est une relation un à plusieurs.
Classe d’album
@Entity public class Album { @Id @GeneratedValue(strategy=GenerationType.AUTO) Integer albumId; Ssortingng albumName; @OneToMany(targetEntity=Photo.class,mappedBy="album",cascade={CascadeType.ALL},orphanRemoval=true) Set photos = new HashSet (); }
Cours de photo
@Entity public class Photo{ @Id @GeneratedValue(strategy=GenerationType.AUTO) Integer photo_id; Ssortingng photoName; @ManyToOne(targetEntity=Album.class) @JoinColumn(name="album_id") Album album; }
Ce que vous devez faire avant de continuer ou de fusionner est de définir la référence de l’album dans chaque photo.
Album myAlbum = new Album(); Photo photo1 = new Photo(); Photo photo2 = new Photo(); photo1.setAlbum(myAlbum); photo2.setAlbum(myAlbum);
C’est comment attacher l’entité associée avant de persister ou de fusionner.
L’erreur se produit car l’ID de l’object est défini. Hibernate distingue les objects transitoires et détachés et persist
uniquement avec les objects transitoires. Si persist
conclut que l’object est détaché (ce qui sera le cas parce que l’ID est défini), il retournera l’erreur “object détaché passé pour persister”. Vous pouvez trouver plus de détails ici et ici .
Cependant, cela ne s’applique que si vous avez spécifié la clé primaire à générer automatiquement: si le champ est configuré pour toujours être défini manuellement, votre code fonctionne.
retirer
user.setId(1);
car il est généré automatiquement sur la firebase database et continue avec la commande persist.
J’ai eu la réponse, j’utilisais:
em.persist(user);
J’ai utilisé la fusion au lieu de persister:
em.merge(user);
Mais aucune idée, pourquoi persister n’a pas fonctionné. 🙁
si vous utilisez pour générer la stratégie id = GenerationType.AUTO
dans votre entité.
Remplace user.setId (1)
par user.setId (null)
et le problème est résolu.
Je sais que c’est trop tard et que tout le monde a la réponse. Mais un peu plus à append à cela: lorsque GenerateType est défini, persist () sur un object doit générer un identifiant.
Si l’utilisateur définit déjà une valeur à Id, la mise en veille prolongée le considère comme un enregistrement enregistré et est donc traité comme étant détaché.
si l’identifiant est nul – dans cette situation, une exception de pointeur nul est levée lorsque le type est AUTO ou IDENTITY, etc. sauf si l’ID est généré à partir d’une table ou d’une séquence etc.
design: cela se produit lorsque la table a une propriété bean comme clé primaire. GenerateType doit être défini uniquement lorsqu’un identifiant est généré automatiquement. Supprimez ceci et l’insert devrait fonctionner avec l’ID spécifié par l’utilisateur. (c’est une mauvaise conception d’avoir une propriété mappée sur le champ clé primaire)
Ici, seulement .persist () insérera l’enregistrement. Si nous utilisons .merge (), il vérifiera s’il existe un enregistrement avec l’ID actuel. S’il existe, il sera mis à jour, sinon il insérera un nouvel enregistrement.
J’ai eu ce problème et il a été causé par le cache de second niveau:
Par conséquent, le cache n’étant pas invalidé, hibernate supposait qu’il s’agissait d’une instance détachée de la même entité.
Si vous définissez id dans votre firebase database comme clé primaire et incrémentation automatique, cette ligne de code est incorrecte:
user.setId(1);
Essayez avec ceci:
public static void main(Ssortingng[] args){ UserBean user = new UserBean(); user.setUserName("name1"); user.setPassword("passwd1"); em.persist(user); }
Une autre raison de l’erreur que votre object entité n’implémente pas l’interface Serializable
@Entity @Table(name = OddInstance.objectName, uniqueConstraints = @UniqueConstraint(columnNames = {"alias"})) @NamedQueries({ @NamedQuery(name=OddInstance.findByAlias, query="from OddInstance where alias = :alias"), @NamedQuery(name=OddInstance.findAll, query="from OddInstance") }) public class OddInstance implements Serializable { // ... }