2011-02-26 38 views
17

Intento persistir un objeto en una base de datos. Sigue obteniendo 'Column ID no puede aceptar el error de valor nulo'. Mi objetivo es el siguiente:@GeneratedValue (strategy = GenerationType.AUTO) no funciona como pensaba

@Entity 
public class TestTable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Integer id = 0; 

    @Column(nullable=false, length=256) 
    private String data = ""; 

    public Integer getId() { 
     return id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 

    public String getData() { 
     return data; 
    } 

    public void setData(String data) { 
     this.data = data; 
    } 

} 

Mi persisten función:

public static synchronized boolean persistObject(Object obj){ 
     boolean success = true; 
     EntityManager em = null; 
     EntityTransaction tx = null; 
     try{ 
      em = getEmf().createEntityManager(); 
      tx = em.getTransaction(); 
      tx.begin(); 
      em.persist(obj); 
      tx.commit(); 

     } catch (Exception e){ 
      success = false; 
     } finally{ 
      try{ 
       em.close(); 
      } catch(Exception e){ 
       //nothing 
      } 
     } 
     return success; 
    } 

Respuesta

19

Usted puede utilizar GenerationType.TABLE. De esta forma, jpa usa una tabla de secuencia para la asignación de ID y es posible que nunca necesite generar valores de secuencia o autoincrementar o desencadenantes que reduzcan la portabilidad.

También tenga en cuenta que en java int tipo se inicia con 0 por defecto, por lo que puede deshacerse de eso también.

+0

@Null: A continuación, acepte la respuesta (haciendo clic en la marca de verificación junto a ella) para que el cguler reciba una pequeña recompensa por ofrecerla. Hacerlo también ayuda a alentar a otros a responder bien a sus otras preguntas. –

+1

@cguler Esto también funcionó para mí, pero no sé por qué GenerationType.Table funciona y Auto no funciona. ¿Puedes explicarme o referirme? –

+2

@ChristianVielma el punto es que AUTO se configura de manera predeterminada como IDENTIDAD. Es posible que deba probar GenerationType.IDENTITY explícitamente y ver si funciona para ver si se trata de un problema con la configuración AUTO. Pero probablemente su configuración de db no lo admite. Sin embargo, GenerationType.TABLE crea una tabla y la usa para generar las claves, y esta configuración debería funcionar en todas las rdbms. Espero que esto ayude :) –

0

O pruebe con @GeneratedValue(strategy = GenerationType.AUTO) en lugar de @GeneratedValue(strategy = GenerationType.SEQUENCE).

+2

o pruebe @Id @GeneratedValue (strategy = GenerationType.IDENTITY) –

2

Tuve un problema con una manifestación similar a la tuya. Eventualmente descubrí que la configuración de mi conexión a la base de datos era incorrecta: me estaba conectando a una base de datos anterior que tenía un esquema incorrecto. El nuevo esquema declaró la columna de clave primaria como

"ID" BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1)

por lo the database itself automatically generated the primary key mientras que el viejo esquema declaró como

"ID" INTEGER NOT NULL

Hibernate ejecuta el código correcto para el nuevo esquema, que falló en el esquema anterior porque t El esquema anterior exigía que el SQL INSERT proporcionara un valor para la columna ID.

1

Hibernate falla de manera silenciosa y misteriosa cuando la columna ID es un Int. Intente cambiarlo por Long en el código y un entero de 64 bits sin signo en la base de datos. Eso solucionó el problema para mí.

4

En mi caso se trataba de mala dialecto:

hibernate.dialect=org.hibernate.dialect.H2Dialect 

en lugar de:

hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect 

cuando me cambiaron a la base de datos de producción. Hibernate intentó utilizar la estrategia preparada para diferentes motores db.

Cuestiones relacionadas