2012-03-30 23 views
16

Estoy usando un db relacional usando una sola columna pk con algunas tablas anidadas. Necesito agregar un archivo simple a mi proyecto. El archivado solo ocurre cuando la aplicación alcanza un estado particular, entonces lo que esperaba hacer era copiar mi objeto de hibernación existente en una nueva instancia donde la nueva instancia se guardará con una nueva ID, dejando intacto el objeto existente. Parece que no puedo entender cómo copiar el objeto existente en una nueva instancia sin tener que configurar manualmente cada campo de instancia nuevo. ¿Alguien sabe de una manera simple de hacer esto?hibernate los valores de los objetos de copia en un nuevo objeto con el nuevo ID generado

Respuesta

6

También estoy trabajando con Hibernate y obtuve el mismo requisito que obtuviste. Lo que seguí fue implementar Cloneable. A continuación se muestra un ejemplo de código de cómo hacerlo.

class Person implements Cloneable { 

     private String firstName; 
     private String lastName; 

     public Object clone() { 

      Person obj = new Person(); 
      obj.setFirstName(this.firstName); 
      obj.setLastName(this.lastName); 

      return obj; 
     } 

     public String getFirstName() { 
      return firstName; 
     } 

     public void setFirstName(String firstName) { 
      this.firstName = firstName; 
     } 

     public String getLastName() { 
      return lastName; 
     } 

     public void setLastName(String lastName) { 
      this.lastName = lastName; 
     } 
    } 

O podría ir a una solución basada en la reflexión, pero no lo recomendaré. Compruebe esto website para más detalles.

+1

¿Cómo se manejan las tablas anidadas, como oneToMany, etc.? Tenía miedo de tener que volver a establecer todas las variables del objeto.:( –

+1

Mi caso no tenía que ver con objetos anidados, así que no me enfrenté a ese problema ... Me temo que tendrás que copiar en profundidad ... Siempre hay generación que se puede hacer ... – Chan

+0

¿Podría señalarme? a un artículo sobre la generación? –

2

Puede clonar el objeto y borrar la identificación y guardarla de nuevo para que se le asigne una nueva identificación.

así

Person person = EmployeeDAO.get(empId); 
Person newPersonCopy = person.createCopyWithNoId() 
EmployeeDAO.add(newPersonCopy); 

en este caso el createCopyWithNoId() crearía un clon del objeto y establecer el campo Id a null. cuando agregue el nuevo clon, el motor de hibernación lo verá ya que un nuevo objeto lo mantendrá y la base de datos asignará una nueva clave principal.

Observe que evité llamar al método clone porque lo que sale no es un clon exacto ya que manipulamos el Id (configurándolo nulo);

Otra forma de hacerlo sería agregar un constructor que tomara un objeto de tipo persona y creara un nuevo objeto, pero simplemente no configuró el campo Id dejándolo en su valor predeterminado de nulo. De nuevo, persiste usando el DAO.

+1

Podría explicar un poco más sobre esto. No estoy del todo seguro de lo que es createCopyWithNoId. Creo que es donde necesito una aclaración. Además, ¿podría esto realizar un clon profundo? –

0

O bien puede clonar si el objeto es clonable o puede definir un método/constructor para el objeto que desea copiar tomando un parámetro de sí mismo y copiando todo lo que necesita, en una nueva instancia y devolvérselo.

23

Simplemente recupere el objeto, sepárelo, establezca el identificador en nulo y consérvelo.

MyEntity clone = entityManager.find(MyEntity.class, ID); 
entityManager.detach(clone); 
clone.setId(null); 
entityManager.persist(clone); 

Si el objeto tiene relaciones uno a muchos, que tendrá que repetir la operación para todos los niños, pero el establecimiento de su Identificación del objeto padre (generada después de la llamada persist) en lugar de null.

Por supuesto, tendrá que eliminar CASCADE persist en sus relaciones con OneToMany, de lo contrario su persistirá creará duplicados de todos los elementos secundarios en las fallas de DB o fk constraint.

+0

funciona como esperaba –

+0

Esperaba que este enfoque funcionara pero .... sorpresa, sorpresa I una excepción org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke() al intentar restablecer el id – Legna

+1

en un niño? ¿Lo separó bef mineral ? (detach no es recursivo a menos que con cascadeType = DETACH) – Gab

Cuestiones relacionadas