Mientras yo trato de guardar nivel superior de la entidad (usando JPA), ¿qué necesito para obtener la ManyToOne entidad asignada recién a partir de la base de datos y establecer o no acabo de Identificador de conjunto (de manyToOne entidad asignada y guardar nivel superior de la entidad?
Cuando no se consigue fresco de la entidad lanza: org.hibernate.TransientObjectException:

Estructuras de la tabla que estamos usando:

DEPARTMENT(DEPARTMENT_ID BIGINT, NAME VARCHAR(128))

EMPLOYEE(EMPLOYEE_ID BIGINT, NAME VARCHAR(128), DEPARTMENT_ID BIGINT)

Entities:
class Department
{
   @Id
   Long departmentId;
   String name;
   @Version
   Long versionNumber;
}

class Employee
{
   @Id
   Long employeeId;
   String name;
   @ManyToOne
   Department department;
   @Version
   Long versionNumber
}

(ambas clases tienen setter y getter métodos para todos los campos y constructor, constructor que toma la clave primaria como argumento)
Ahora si quiero guardar los Empleados con departmentId (digamos 100), necesito el Departamento de registro y, a continuación, en los empleados?

No puedo crear la instancia del Departamento directamente (mediante la configuración de la clave primaria(departmentId)) y establecer Departamento instancia de los Empleados y de guardar Empleado?
Cuando hago esto es tirar org.hibernate.TransientObjectException.

Sugerencias sobre la mejor práctica a seguir para esto?

Gracias de antemano

InformationsquelleAutor Kumar D | 2009-12-14

3 Comentarios

  1. 7

    Si quieres asociar tu Employee instancia con nueva Departamento de ejemplo, puede establecer un adecuado comportamiento en cascada y dejar Hibernar tomar el cuidado de todo el asunto:

    class Employee {
      ...
      @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
      Department department;
    }

    Tenga en cuenta que NO desea utilizar CascadeType.ALL porque la eliminación de un empleado no debe eliminar un departamento.

    Si, OTOH, desea asociar su Employee instancia con existente Departamento de ejemplo, el mejor enfoque es, de hecho, a la carga. Usted puede utilizar período de sesiones.load() método para tal fin, que no llegará a la base de datos.

    Una solución alternativa es utilizar período de sesiones.merge() en Employee que (con cascada como se indica anteriormente) que se propagan a Department. Esto puede tener efectos secundarios, aunque.

    • Ah, mi mal, me perdí en la tipificación de que era @ManyToOne en lugar de viceversa. Sí, En Cascada.Todo iba a ser malo!
    • Gracias. Mi requisito es poco diferente. Yo no quiero pegarle a la base de datos.
    • Como he dicho anteriormente, el uso de session.load() – que no llegará a la base de datos hasta que ras / commit.
    • puedes mirar en mi pregunta así.stackoverflow.com/questions/26284974/… Kumar D respuesta es la única manera de seguir adelante con este tema
  2. 1

    Si desea guardar los padres sin guardar cada uno de los niños, es necesario asignar algo así como (no recuerdo la sintaxis exacta)

    @ManyToOne(CascadeType = Cascade.All)
    Department department;

    EDIT: he cometido el error de ver como de padre a hijo, en vez de hijo a padre. Siga ChssPly76 del ejemplo.

  3. 1

    Gracias ChssPly76 y Wysawyg.

    Uno de la solución podría ser:
    Vamos a actualizar Empleado POJO de la siguiente

    ManyToOne(fetch=FetchType.EAGER)
    @**JoinColumn**(name = "DEPARTMENT_ID", referencedColumnName = "DEPARTMENT_ID", **insertable=false, updatable=false**)
    private Department department;
    
    @Column(name = "department_id")
    private Long departmentId;

    (ambos del departamento y departmentId tendrá setter y getter métodos)

    y Ahora aquí (por favor, ver que tanto el departamento y departmentId asignado a la misma columna (DEPARTMENT_ID)
    utilizamos departamento sólo para ir a buscar Departamento de detalles
    y departmentId para insertar o actualizar Empleado

    Pero estoy preocupado por si es un mejor enfoque.

    • No sé quién ha votada abajo esto? Pueden justificar por favor?

Dejar respuesta

Please enter your comment!
Please enter your name here