Hibernate @GeneratedValue(strategy=GenerationType.AUTO)未按预期工作
我正在尝试将对象持久化到数据库。继续获取“列ID不能接受空值错误”。我的对象如下所示:Hibernate @GeneratedValue(strategy=GenerationType.AUTO)未按预期工作,hibernate,jpa,jboss,derby,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 = ""; publi
@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;
}
您可以使用GenerationType.TABLE。 这样,jpa使用序列表进行id分配,您可能永远不需要生成降低可移植性的序列或自动增量值或触发器
另外请注意,在java中,int type是用0默认值启动的,因此您也可以去掉它。或尝试使用
@GeneratedValue(strategy=GenerationType.AUTO)
而不是
@GeneratedValue(strategy=GenerationType.SEQUENCE)
我遇到了一个与您类似的问题。我最终发现数据库连接的配置是错误的:我连接的是一个模式不正确的旧数据库。新架构将主键列声明为
“ID”BIGINT NOT NULL始终作为标识生成(从1开始,递增1)
因此,旧模式将其声明为
“ID”整数不为空
Hibernate为新架构执行了正确的代码,在旧架构上失败,因为旧架构要求SQL
INSERT
为ID
列提供一个值。当ID列为Int时,Hibernate以静默和神秘的方式失败。请尝试在代码中将其更改为Long,在数据库中更改为无符号64位整数。这解决了我的问题。在我的情况下,这是关于糟糕的方言:
hibernate.dialect=org.hibernate.dialect.H2Dialect
而不是:
hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect
当我切换到生产数据库时。Hibernate尝试使用为不同的db引擎准备的策略。以防有人遇到与我相同的问题。我已经为此挣扎了几个小时,现在只想发布我的解决方案。ID似乎总是设置为0,这引发了一个错误 模型中的id属性必须是“Long”或“Integer”类型,而不是“Long”或“Integer”(注意大小写)。我已经输入了“long”,这是一个基本类型,不能为null。因此,默认值为0,Hibernate没有意识到它是一个新实体,并试图用ID=0保存它,这显然是不起作用的
将其更改为引用类型“Long”(可以为null),解决了这个问题。我也遇到了同样的问题,不知何故,对于我来说,Long工作代替了Long类型:)。作为workaround,我将数据库中的id列转换为SERIEL。我正在使用postgres db。@Null:然后接受答案(通过单击旁边的复选标记),这样cguler就可以获得一点奖励。这样做也有助于鼓励其他人很好地回答您的其他问题。@cguler这对我也有用,但我不知道为什么GenerationType.Table可以工作而Auto不能。你能给我解释一下或者介绍我吗?@ChristianVielma问题是,自动默认为身份。您可能需要显式地尝试GenerationType.IDENTITY,并查看它是否有效,以查看是否存在自动设置问题。但您的数据库配置可能不支持它。但是,GenerationType.TABLE会创建一个表并使用它生成键,此设置应适用于所有rdbms。希望这有帮助:)真的谢谢@cguler我会在文档中查看更多关于这方面的信息,看看为什么它不能与我的Postgres配置一起使用。或者试试@Id@GeneratedValue(strategy=GenerationType.IDENTITY)