Tengo una simple entidad JPA que utiliza una generados long «ID» como clave principal:

@Entity
public class Player {
   private long id;

   protected Player() {
     //Do nothing; id defaults to 0L
   }


   @GeneratedValue
   @Id
   public long getId() {
      return id;
   }

   protected void setId(final long id) {
      this.id = id;
   }
   //Other code
}

En un cierto punto en el ciclo de vida de un objeto de este tipo de JPA debe llamar setId() para registrar el ID generado valor. Mi pregunta es, cuando sucede esto, y dónde está la documentación que los estados de este. He mirado a través de la Especificación JPA y no puede encontrar una declaración clara.

La Especificación JPA dice (énfasis añadido):

Una entidad administrada instancia es una instancia con un persistente identidad que está asociada con un contexto de persistencia.

Es que tratando de decir que el objeto debe ser administrado a tener su @Id significativo?
La documentación para EntityManager.persist() dice (énfasis añadido) se hace «una instancia administrado y persistente», así que eso no significa que el @Id es por ese método? O es que no se hasta que llame EntityTransaction.commit()?

Cuando el @Id se establece puede ser diferente para diferentes JPA proveedores, y tal vez por diferentes estrategias de generación. Pero ¿cuál es la más segura (portátil, conforme a la especificación) suposición de que usted puede hacer sobre el primer punto en el ciclo de vida que se ha establecido?

  • Suena como algo que se puede establecer con bastante facilidad con la depuración.
  • Yo apostaría que si las especificaciones no dicen explícitamente cuando el @Id debe ser generado de la izquierda para los vendedores para decidir.
  • La depuración le dirá cómo JPA trabaja internamente, y decirles que los bits se dialecto específico.
  • Relacionados, pero no duplicar la pregunta: stackoverflow.com/questions/8169640/…
InformationsquelleAutor Raedwald | 2012-01-31

4 Comentarios

  1. 21

    de llamadas .persist() no establece automáticamente el valor de id. Su JPA proveedor se asegurará de que se establece antes de que la entidad es, por último escrito db. Así que estás en lo cierto al suponer que el id se asigna cuando se confirma la transacción. Pero este no es el único caso posible. Cuando usted llame .flush() el mismo que va a suceder.

    Thomas

    Actualización: prestar atención a la Friki del comentario, por favor. -> Si GenerationType.Se usa la identidad, la identificación no será establecido por el proveedor antes de que la entidad está escrito db. En este caso, identificación de la generación que sucede durante el proceso de insertar en el nivel de db. De todos modos, la JPA proveedor se asegurará de que la entidad se actualiza después y el identificador generado estará disponible en el @Id anotado propiedad.

    • Suena razonable. Por lo tanto, si usted llama EntityManager.flush() puede usted confiar en la @Generated @Id después de haber sido creado? No puedo encontrar pistas en la documentación.
    • Usted también puede tener un vistazo a este post en el modo hibernación foro: forum.hibernate.org/viewtopic.php?p=2384011#p2384011 parece depender elegido generador de estrategia
    • Según el EntityManager documentación docs.oracle.com/javaee/6/api/javax/persistence/… flush va a «Sincronizar el contexto de persistencia a la base de datos subyacente.» Esto significa que todos agrupados instrucciones insert se escriben en la base de datos para sincronizar estado. Para ello su JPA proveedor de las necesidades de los valores de id. Por lo que debe estar disponible después de llamar a ras. Algunas estrategias que se podrían establecer con anterioridad, aunque.
    • Creo que lo he encontrado, pero me gustaría que la documentación fuera más clara. La parte correspondiente de la especificación es «3.2.4 la Sincronización de la Base de datos: El estado de la persistencia de las entidades que se sincroniza con la base de datos en la confirmación de la transacción. Esta sincronización de redacción a la base de datos de las actualizaciones a la persistencia de las entidades… [incluyendo] la asignación de un nuevo valor a una propiedad persistente o en el campo… La flush método puede ser utilizado por la aplicación para forzar la sincronización.»
    • usted podría sugerir algunos cambios o aclaraciones a las JPA 2.1 Grupo de Expertos – es decir, a través de su lista de correo.
    • Usted escribió «Su JPA proveedor se asegurará de que se establece antes de que la entidad es, finalmente, escrita a db». Esto no es del todo correcta, porque si usted está usando strategy=GenerationType.IDENTITY, entonces es realmente disponible sólo después de que la entidad está escrito a la db no antes de que se escriben en la base de datos.

  2. 11

    AFAIK, el ID sólo está garantizada para ser asignado cuando el contexto de persistencia se vacían. Podría ser asignado antes, pero depende de la estrategia de generación.

  3. 8

    El libro de Empresa JavaBeans 3.1 por Rubinger y Burke dice lo siguiente, en la página 143 (énfasis añadido):

    De Persistencia Java también puede ser configurado para generar automáticamente una clave principal cuando el persist() método se invoca a través del uso de la @GeneratedValue anotación en la cima de el campo de clave principal o setter. Así, en el ejemplo anterior, si hemos tenido automático de generación de la clave habilitada, se puede ver la clave generada después de la persist() método completado.

    La Especificación JPA dice (énfasis añadido):

    Una entidad administrada instancia es una instancia con un persistente identidad que está asociada con un contexto de persistencia.

    Y también que EntityManager.persist() hace

    una instancia administrada y persistente

    Como el @Id es crucial para el identidad de una entidad, la única manera para EntityManager.persist() para hacer que el objeto administrado es establecer su identidad mediante la generación de la @Id.


    Sin embargo

    Rubinger y Buke del declaración clara es incompatible con el comportamiento de la Hibernación. Así que parece que las personas bien informadas disgree acerca de lo que la especificación JPA tiene la intención.

  4. 4

    Según JSR 338: JavaTM Persistencia 2.1 /3.5.3 Semántica del Ciclo de Vida de los Métodos de devolución de llamada para las Entidades,

    La PostPersist y PostRemove métodos de devolución de llamada se invocan para una entidad después de que la entidad ha sido persistente o eliminado. Estas devoluciones de llamada también se invoca en todas las entidades para que estas operaciones se conectan en cascada. El PostPersist y PostRemove métodos se invoca después de la base de datos de operaciones de inserción y eliminación, respectivamente. Estas operaciones de base de datos puede ocurrir directamente después de la persistir, combinar o eliminar las operaciones han sido invocada o pueden ocurrir directamente después de una operación de vaciado se ha producido (que puede estar en la final de la transacción). Genera valores de clave principal están disponibles en el PostPersist método.

    Una posible (personalmente presumible) excepción es GeneratorType.La TABLA que el contenedor (mayo) recupera los valores de uso y de (mayo) establece que antes de PrePersist. Yo siempre uso mi id en PrePersist. No estoy seguro de que este tipo de comportamientos es especificado o no puede trabajar con cualquier otros proveedores.

    importante editar

    No todos los servidores de aplicaciones identificador de conjunto antes de PrePersist. Usted puede realizar el seguimiento de JPA_SPEC.

Dejar respuesta

Please enter your comment!
Please enter your name here