2011-11-17 18 views
6

See this question.¿Cómo obtiene una entidad una identificación antes de comprometerse una transacción en JPA/Play?

Resulta que, incluso sin comprometer la transacción manualmente, antes de confirmar la transmisión, la persona tiene una identificación después de llamar al método save().

¿No es la base de datos responsable de asignar el campo ID? Si es así, ¿cómo se puede llenar el campo ID antes de confirmar? ¿Se produce alguna comunicación con el DB antes de confirmar la transmisión?

Respuesta

9

Sí, el JPA puede comunicarse con el DB antes de la confirmación de la transacción. Puede ocurrir, es decir, cuando invocas explícitamente EntityManager#flush().

Además, el proveedor de JPA puede realizar la operación de descarga cuando lo considere necesario. Sin embargo, por la conveniencia, los proveedores de JPA retrasan las operaciones de DB hasta el momento en que se comprometerá la transacción.

Algunas estrategias de generador de ID automático deben golpear la base de datos para obtener el valor de PK (hasta donde recuerdo la estrategia IDENTITY funciona de esa manera).
Por el contrario, los generadores TABLE o SEQUENCE no necesitan golpear el DB para obtener el valor de ID. Utilizan el parámetro allocationSize para solicitar a DB TABLE o SEQUENCE un lote de identificadores que se entregarán a entidades nuevas sin comunicación adicional con la base de datos.

3

Play! está vaciando el contexto de persistencia (que escribe cambios en la base de datos y le permite obtener el ID generado) cada vez que guarda un objeto usando el método save() en el modelo:

Desde el código fuente JPABase._save() :

if (!em().contains(this)) { 
    em().persist(this); 
    PlayPlugin.postEvent("JPASupport.objectPersisted", this); 
} 
// ... 
try { 
    em().flush(); 
} catch (PersistenceException e) { 
    // ... 
} 
0

que yo sepa, no podemos obtener el id del objeto (se supone que es un auto-numerada) antes de que persistió. y personalmente creo que es bastante peligroso asignar algo que debe ser hecho por RDBMS fuera de él.

+0

¿Por qué? JPA se ocupa de ello ... y si, por casualidad, la identificación no estará disponible cuando usted realice la transacción, fallará ... siempre que sepa que la transacción puede fallar (por cualquier razón), Creo que usar el ID temprano está bien. – ripper234

0

Entre BeginTransaction y comprometerse, después de la llamada guardar o método de actualización, se debe utilizar:

EntityManagerHelper.getEntityManager().flush(); 

Si no llamarlo, se perderá el objeto y no puede ser excepto a DB.

Así que después de llamarlo, tomará su identificación en el objeto.

Cuestiones relacionadas