@GeneratedValue(strategy = GenerationType.AUTO)没有像想象的那样工作

时间:2011-02-26 20:30:46

标签: hibernate jpa jboss derby

我正在尝试将对象持久化到数据库。继续获取'列ID不能接受空值错误'。我的对象看起来像这样:

    @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;
    }

}

我的坚持功能:

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;
    }

7 个答案:

答案 0 :(得分:21)

您可以使用GenerationType.TABLE。 这样,jpa使用序列表进行id分配,您可能永远不需要生成序列或自动递增值或触发器,从而降低可移植性。

另请注意,在java int类型中,默认启动为0,因此您也可以将其删除。

答案 1 :(得分:4)

就我而言,这是关于糟糕的方言:

hibernate.dialect=org.hibernate.dialect.H2Dialect

而不是:

hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect

当我切换到生产数据库时。 Hibernate试图使用为不同的db引擎准备的策略。

答案 2 :(得分:2)

我遇到了类似表现的问题。我最终发现我的数据库连接的配置是错误的:我正在连接到具有不正确架构的旧数据库。新架构将主键列声明为

  

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

所以the database itself automatically generated the primary key而旧架构将其声明为

  

"ID" INTEGER NOT NULL

Hibernate为新架构执行了正确的代码,该架构在旧架构上失败,因为旧架构要求SQL INSERTID列提供值。

答案 3 :(得分:1)

当ID列是Int时,Hibernate以静默和神秘的方式失败。尝试在代码中将其更改为Long,并在数据库中将其更改为无符号的64位整数。这解决了我的问题。

答案 4 :(得分:1)

以防万一有人遇到与我相同的问题而到达此线程。我已经为此奋斗了几个小时,只想发布我的解决方案。似乎ID始终设置为0,这引发了错误。

模型中的id属性必须是“ Long”或“ Integer”类型,而不是“ long”或“ integer”(请注意大写)。我输入了“ long”,这是一个原始类型,不能为null。因此默认值为0,而Hibernate并未意识到这是一个新实体,并尝试将其保存为ID = 0,这显然是行不通的。

将其更改为引用类型“ Long”(可以为null)即可解决该问题。

答案 5 :(得分:0)

或尝试使用@GeneratedValue(strategy = GenerationType.AUTO) 而不是@GeneratedValue(strategy = GenerationType.SEQUENCE)

答案 6 :(得分:0)

我一直在同一个问题上挣扎,而不是LONG类型:)我需要长时间工作。作为工作环境,我将数据库中的id列转换为SERIEL。我正在使用postgres db。