tutorial query namedquery example español ejemplos create java jpa ejb-3.0

java - query - jpql



"Entidad separada pasada al error persistir" con el código JPA/EJB (10)

Estoy tratando de ejecutar este código JPA / EJB básico:

public static void main(String[] args){ UserBean user = new UserBean(); user.setId(1); user.setUserName("name1"); user.setPassword("passwd1"); em.persist(user); }

Me sale este error:

javax.ejb.EJBException: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.JPA.Database

¿Algunas ideas?

Busco en internet y la razón que encontré fue:

Esto fue causado por la forma en que creó los objetos, es decir, si establece la propiedad de ID explícitamente. Eliminar la asignación de ID lo solucionó.

Pero no lo obtuve, ¿qué tendré que modificar para que el código funcione?


Aquí .persist () solo insertará el registro. Si usamos .merge () , se comprobará si existe algún registro con el ID actual. Si existe, se actualizará o, de lo contrario, insertará un nuevo registro.


El error ocurre porque la identificación del objeto está configurada. Hibernate distingue entre objetos transitorios y separados y persist funciona solo con objetos transitorios. Si la persist concluye que el objeto está separado (lo cual ocurrirá porque la ID está configurada), devolverá el error "objeto separado pasado para persistir". Puede encontrar más detalles here y here .

Sin embargo, esto solo se aplica si ha especificado la clave primaria que se generará automáticamente: si el campo está configurado para configurarse siempre manualmente, su código funciona.


Obtuve la respuesta, estaba usando:

em.persist(user);

Usé la fusión en lugar de persistir:

em.merge(user);

Pero ni idea, por qué persistir no funcionó. :(


Otro motivo de error es que su objeto entidad no implementa la interfaz 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 { // ... }


Sé que es demasiado tarde y prolijo, todos obtuvieron la respuesta. Pero un poco más para agregar a esto: cuando se establece GenerateType, se espera que persistir () en un objeto genere una identificación.

Si el usuario ya tiene un valor establecido para el Id, hibernate lo trata como un registro guardado, por lo que se trata como separado.

si el ID es nulo, en esta situación se genera una excepción de puntero nulo cuando el tipo es AUTO o IDENTIDAD, etc., a menos que el ID se genere a partir de una tabla, una secuencia, etc.

diseño: esto sucede cuando la tabla tiene una propiedad de frijol como clave principal. GenerateType debe establecerse solo cuando una identificación se genera automáticamente. elimine esto y la inserción debería funcionar con la identificación especificada por el usuario. (es un mal diseño tener una propiedad asignada al campo de clave principal)


Si configura el id en su base de datos para que sea la clave principal y el autoincremento, entonces esta línea de código es incorrecta:

user.setId(1);

Prueba con esto:

public static void main(String[] args){ UserBean user = new UserBean(); user.setUserName("name1"); user.setPassword("passwd1"); em.persist(user); }


Tuve este problema y fue causado por el segundo nivel de caché:

  1. Persistí una entidad que usa Hibernate
  2. Luego borré la fila creada de un proceso separado que no interactuó con el segundo nivel de caché
  3. Persistí a otra entidad con el mismo identificador (mis valores de identificador no se generan automáticamente)

Por lo tanto, debido a que el caché no fue invalidado, hibernación asumió que se trataba de una instancia separada de la misma entidad.


retirar

user.setId(1);

porque se genera automáticamente en la base de datos y continúa con el comando persistir.


si usa para generar la estrategia id = GenerationType.AUTO en su entidad.

Reemplaza user.setId (1) por user.setId (null) , y el problema está resuelto.


Digamos que tiene dos entidades, Album y Photo . El álbum contiene muchas fotos, por lo que es una relación de uno a muchos.

Clase de álbum

@Entity public class Album { @Id @GeneratedValue(strategy=GenerationType.AUTO) Integer albumId; String albumName; @OneToMany(targetEntity=Photo.class,mappedBy="album",cascade={CascadeType.ALL},orphanRemoval=true) Set<Photo> photos = new HashSet<Photo>(); }

Clase de fotografía

@Entity public class Photo{ @Id @GeneratedValue(strategy=GenerationType.AUTO) Integer photo_id; String photoName; @ManyToOne(targetEntity=Album.class) @JoinColumn(name="album_id") Album album; }

Lo que debe hacer antes de persistir o fusionar es establecer la referencia del álbum en cada fotografía.

Album myAlbum = new Album(); Photo photo1 = new Photo(); Photo photo2 = new Photo(); photo1.setAlbum(myAlbum); photo2.setAlbum(myAlbum);

Así es como adjuntar la entidad relacionada antes de persistir o fusionarse.