2011-02-02 13 views
7

estoy usando APP vínculo superior esencial y SQL Server 2008¿Por qué persiste JPA() no genera ID principal de incremento automático?

Mi objetivo es conseguir que el valor de clave principal incremento automático de los datos que se va a insertar en la tabla. Sé en JDBC, hay getInsertedId() como método que le da el id. De autoincremento de ID principal (pero eso es después de la instrucción de inserción ejecutada)

En JPA, descubrí que @GenratedValue annotation puede hacer el truco.

@Entity 
@Table(name = "tableOne") 
public class TableOne implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    @Basic(optional = false) 
    @Column(name = "tableId") 
    private Integer tableId; 

Ahora bien, si corro el código de abajo se debe dame el auto incrementado Identificación pero devuelve NULL ...

EntityManager em = EmProvider.getInstance().getEntityManagerFactory().createEntityManager(); 
EntityTransaction txn = em.getTransaction(); 
txn.begin(); 

TableOne parent = new TableOne(); 
em.persist(parent); //here I assume that id is pre-generated for me. 
System.out.println(parent.getTableId()); //this returns NULL :(
+0

Puedo obtener ID si confirmo: em.getTransaction(). Commit() pero no hay manera de obtener ID con persistencia ??? hmm –

+0

Su código debería funcionar como esperaba. Lo probé y obtuve la identificación antes de comprometerme o si luego retrocedí. Es extraño que no. – Joel

+0

¿Hay alguna diferencia si tableId es un int en lugar de un entero? – Joel

Respuesta

2

También estamos utilizando SQL Server 2008 y se nunca funcionó para mí, así que siempre ejecuto la consulta separada "SELECT @@IDENTY" para obtener la identificación insertada.

La razón que encontré en la red fue que el ID automático (IDENTIDAD) es administrado por la base de datos y nunca se ingresó en Entidad hasta que a menos que usted confirme la fila o recupere manualmente la información de la base de datos.

+0

¿Quiere decir que debido a SQL Server 2008, no podemos usar @ GeneratedValue.Sequence o Table or Identity ??? Pensé que tenía que lavar primero (insertar llamada a db para obtener la identificación generada) pero mi objetivo es sin insertar llamada si puedo obtener la identificación primaria. –

+0

Puede estar en lo cierto, el documento no parece incluir SQL Server para admitir el objeto SEQUENCE .... "Los objetos de secuencia utilizan objetos de base de datos especiales para generar identificadores. Los objetos de secuencia solo son compatibles con algunas bases de datos, como Oracle, DB2, y Postgres ". http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Table_sequencing –

+0

marcando como respuesta, SEQUENCE no está siendo soportado por SQL Server –

11

El problema es que está utilizando IDENTITY id generation. La generación de id. De IDENTIDAD no puede realizar la asignación previa ya que requieren el INSERT para generar el id. La preasignación de soporte de generación de ID de TABLE y SEQUENCE, y siempre recomendaría su uso, y nunca usar IDENTITY debido a este problema y debido al rendimiento.

Puede activar el ID que se generará al usar IDENTITY id generation llamando a flush().

+0

hmmm sequence not working for me. Cambié mi anotación en clase de entidad a: '@Id @SequenceGenerator (name =" seq ", sequenceName =" seq ") @GeneratedValue (strategy = GenerationType.SECUENCIA, generador = "seq") ' –

+1

Luego después de em.persist (myBean); int insertedId = myBean.getId(); Este getId() está devolviendo nulo ... ¿estoy haciendo algo mal? –

+1

Eso es un problema de tiempo. JPA no insertó los datos cuando intenta obtener el valor de identificación. Debe enjuagar para que comience a hacer las modificaciones en la base de datos. Luego tienes la identificación. Mejor sería que JPA haga las modificaciones en el DB cuando llame a getId(). –

6

simplemente hacer esto:

public void create(T entity) { 
    getEntityManager().persist(entity); 
    getEntityManager().flush(); 
    getEntityManager().refresh(entity); 
} 

Después de la actualización de la entidad que tiene el campo ID con el valor apropiado.

+3

El motivo para agregar 'flush()' es que 'persist()' no garantiza claramente que haya generado '@ GeneratedValue', pero debe generarse en o antes de' flush() '. Vea esta pregunta: http://stackoverflow.com/questions/9087848/when-does-the-jpa-set-a-generatedvalue-id – Raedwald

Cuestiones relacionadas