Hibernate: “ Field‘ id’没有默认值”

我认为 Hibernate 面临的问题很简单,但却无法解决(Hibernate 论坛无法访问肯定没有帮助)。

我有一个简单的类,我想坚持下去,但不断得到:

SEVERE: Field 'id' doesn't have a default value
Exception in thread "main" org.hibernate.exception.GenericJDBCException: could not insert: [hibtest.model.Mensagem]
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
[ a bunch more ]
Caused by: java.sql.SQLException: Field 'id' doesn't have a default value
[ a bunch more ]

持久化类的相关代码是:

package hibtest.model;


import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;


@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Mensagem  {
protected Long id;


protected Mensagem() { }


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


public Mensagem setId(Long id) {
this.id = id;
return this;
}
}

实际的运行代码很简单:

SessionFactory factory = new AnnotationConfiguration()
.configure()
.buildSessionFactory();


{
Session session = factory.openSession();
Transaction tx = session.beginTransaction();


Mensagem msg = new Mensagem("YARR!");


session.save(msg);


tx.commit();
session.close();
}

我在 GeneratedValue注释中尝试了一些“策略”,但它似乎不起作用。初始化 id也没有帮助!(例如 Long id = 20L)。

有人能透露点消息吗?

编辑2: 确认: 干扰 @GeneratedValue(strategy = GenerationType.XXX)并不能解决问题

重建数据库解决了这个问题

271882 次浏览

看看 GeneratedValue的策略,它通常是这样的:

@GeneratedValue(strategy=GenerationType.IDENTITY)

有时对模型或 ORM 所做的更改可能不能准确地反映在数据库中,即使在执行 SchemaUpdate之后也是如此。

如果错误实际上似乎缺乏合理的解释,请尝试重新创建数据库(或者至少创建一个新的数据库) ,并使用 SchemaExport为其搭建脚手架。

将方法 hashCode()添加到实体 Bean 类中并重试

请检查特定 table.if 列 id 的默认值是否为默认值

如果您希望 MySQL 自动生成主键,那么您必须在创建表时告诉它。在甲骨文你不必这么做。

在主键上你必须包括 AUTO_INCREMENT。参见下面的例子。

CREATE TABLE `supplier`
(
`ID` int(11) NOT NULL **AUTO_INCREMENT**,
`FIRSTNAME` varchar(60) NOT NULL,
`SECONDNAME` varchar(100) NOT NULL,
`PROPERTYNUM` varchar(50) DEFAULT NULL,
`STREETNAME` varchar(50) DEFAULT NULL,
`CITY` varchar(50) DEFAULT NULL,
`COUNTY` varchar(50) DEFAULT NULL,
`COUNTRY` varchar(50) DEFAULT NULL,
`POSTCODE` varchar(50) DEFAULT NULL,
`HomePHONENUM` bigint(20) DEFAULT NULL,
`WorkPHONENUM` bigint(20) DEFAULT NULL,
`MobilePHONENUM` bigint(20) DEFAULT NULL,
`EMAIL` varchar(100) DEFAULT NULL,
PRIMARY KEY (`ID`)
)


ENGINE=InnoDB DEFAULT CHARSET=latin1;

这是实体

package com.keyes.jpa;


import java.io.Serializable;
import javax.persistence.*;
import java.math.BigInteger;


/**
* The persistent class for the parkingsupplier database table.
*
*/
@Entity
@Table(name = "supplier")
public class supplier implements Serializable
{
private static final long serialVersionUID = 1L;


@Id
**@GeneratedValue(strategy = GenerationType.IDENTITY)**
@Column(name = "ID")
private long id;


@Column(name = "CITY")
private String city;


@Column(name = "COUNTRY")
private String country;


@Column(name = "COUNTY")
private String county;


@Column(name = "EMAIL")
private String email;


@Column(name = "FIRSTNAME")
private String firstname;


@Column(name = "HomePHONENUM")
private BigInteger homePHONENUM;


@Column(name = "MobilePHONENUM")
private BigInteger mobilePHONENUM;


@Column(name = "POSTCODE")
private String postcode;


@Column(name = "PROPERTYNUM")
private String propertynum;


@Column(name = "SECONDNAME")
private String secondname;


@Column(name = "STREETNAME")
private String streetname;


@Column(name = "WorkPHONENUM")
private BigInteger workPHONENUM;


public supplier()
{
}


public long getId()
{
return this.id;
}


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


public String getCity()
{
return this.city;
}


public void setCity(String city)
{
this.city = city;
}


public String getCountry()
{
return this.country;
}


public void setCountry(String country)
{
this.country = country;
}


public String getCounty()
{
return this.county;
}


public void setCounty(String county)
{
this.county = county;
}


public String getEmail()
{
return this.email;
}


public void setEmail(String email)
{
this.email = email;
}


public String getFirstname()
{
return this.firstname;
}


public void setFirstname(String firstname)
{
this.firstname = firstname;
}


public BigInteger getHomePHONENUM()
{
return this.homePHONENUM;
}


public void setHomePHONENUM(BigInteger homePHONENUM)
{
this.homePHONENUM = homePHONENUM;
}


public BigInteger getMobilePHONENUM()
{
return this.mobilePHONENUM;
}


public void setMobilePHONENUM(BigInteger mobilePHONENUM)
{
this.mobilePHONENUM = mobilePHONENUM;
}


public String getPostcode()
{
return this.postcode;
}


public void setPostcode(String postcode)
{
this.postcode = postcode;
}


public String getPropertynum()
{
return this.propertynum;
}


public void setPropertynum(String propertynum)
{
this.propertynum = propertynum;
}


public String getSecondname()
{
return this.secondname;
}


public void setSecondname(String secondname)
{
this.secondname = secondname;
}


public String getStreetname()
{
return this.streetname;
}


public void setStreetname(String streetname)
{
this.streetname = streetname;
}


public BigInteger getWorkPHONENUM()
{
return this.workPHONENUM;
}


public void setWorkPHONENUM(BigInteger workPHONENUM)
{
this.workPHONENUM = workPHONENUM;
}


}

我也有同样的问题。我使用的是一个连接表,而我所有的连接表只有一个行 id 字段和两个外键。我不知道确切的原因,但我做了以下事情

  1. 将 MySQL 升级到社区5.5.13
  2. 重命名类和表
  3. 确保我有散列码和等于方法

    @Entity
    @Table(name = "USERGROUP")
    public class UserGroupBean implements Serializable {
    private static final long serialVersionUID = 1L;
    
    
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name = "USERGROUP_ID")
    private Long usergroup_id;
    
    
    @Column(name = "USER_ID")
    private Long user_id;
    
    
    @Column(name = "GROUP_ID")
    private Long group_id;
    

另一个建议是检查您是否为自动生成的字段使用了有效的类型。请记住,它不适用于 String,但适用于 Long:

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Long id;


@Constraints.Required
public String contents;

上面的语法用于在 MySQL 中使用 Hibernate 作为 JPA 2.0提供程序生成表。

您必须在 hbm2ddl 属性中使用 update。进行更改并将其更新为 Create,以便可以创建表。

<property name="hbm2ddl.auto">create</property>

这招对我很管用。

我来这里是因为错误消息,原来我有两个同名的表。

只需添加非空约束

我也有同样的问题。我只是在 xml 映射中添加了非空约束

<set name="phone" cascade="all" lazy="false" >
<key column="id" not-null="true" />
<one-to-many class="com.practice.phone"/>
</set>

我也遇到了同样的问题。我找到了教程 使用外键注释的 Hibernate 一对一映射示例,并按照下面的步骤一步一步地学习:

使用以下脚本创建数据库表:

create table ADDRESS (
id INT(11) NOT NULL AUTO_INCREMENT,
street VARCHAR(250) NOT NULL,
city  VARCHAR(100) NOT NULL,
country  VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
);


create table STUDENT (
id            INT(11) NOT NULL AUTO_INCREMENT,
name          VARCHAR(100) NOT NULL,
entering_date DATE NOT NULL,
nationality   TEXT NOT NULL,
code          VARCHAR(30) NOT NULL,
address_id INT(11) NOT NULL,
PRIMARY KEY (id),
CONSTRAINT student_address FOREIGN KEY (address_id) REFERENCES ADDRESS (id)
);

下面是具有上述表的实体

@Entity
@Table(name = "STUDENT")
public class Student implements Serializable {


private static final long serialVersionUID = 6832006422622219737L;


@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;


}


@Entity
@Table(name = "ADDRESS")
public class Address {


@Id @GeneratedValue
@Column(name = "ID")
private long id;
}

问题解决了。

注意: 主键必须设置为 AUTO _ INCREMENT

如果 DB 表有一个未删除的旧列,则引发相同的异常。

例如: attribute_id NOT NULL BIGINT(20),attributeId NOT NULL BIGINT(20),

在删除未使用的属性之后,在我的例子中是 合同,问题得到了解决。

我有这个问题,我错误地将 @Transient注释放在那个特定属性之上。在我的情况下,这个错误是有意义的。

这发生在我和 @ManyToMany的关系上。我已经注释了与 @JoinTable关系中的一个字段,我删除了它,而是在@ManyTomany 上使用了 mappedBy属性。

手动从数据库中删除表,然后重新运行应用程序对我来说很有用。我想在我的案例中,表格没有被正确地创建(带有约束)。

除了上面提到的内容之外,别忘了在创建 sql 表时使 自动增量如本例所示

CREATE TABLE MY_SQL_TABLE (


USER_ID INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
FNAME VARCHAR(50) NOT NULL,
LNAME VARCHAR(20) NOT NULL,
EMAIL VARCHAR(50) NOT NULL
);

我尝试了代码,在我的情况下,下面的代码解决了这个问题。我没有正确地解决这个问题

@Entity
@Table(name="table"
,catalog="databasename"
)

请试着像我一样添加 ,catalog="databasename"

,catalog="databasename"

对我来说, 我修改了那个有问题的表和字段“ id”,我把它改成了 AUTO _ INCREMENT,我仍然需要弄清楚为什么在部署时它没有把它改成“ AUTO _ INCREMENT”,所以我必须自己来做!

这个怎么样:

<set name="fieldName" cascade="all">
<key column="id" not-null="true" />
<one-to-many class="com.yourClass"/>
</set>

希望能帮到你。

也许这就是表模式.放下桌子和重新运行应用程序的问题所在。

尝试将 Long对象类型更改为 long基元类型(如果您可以使用基元类型的话)。

我也有同样的问题,改变类型帮助了我。

我有个问题。我的错误在于我将可插入和可更新的文件设置为 false,并试图在请求中设置该字段。此字段在 DB 中设置为 NONNULL。

@ManyToOne
@JoinColumn(name="roles_id",  referencedColumnName = "id", insertable = false, updatable = false, nullable=false)
@JsonBackReference
private Role role;

后来我把它改为-insert table = true,updatable = true

@ManyToOne
@JoinColumn(name="roles_id",  referencedColumnName = "id", insertable = true, updatable = true, nullable=false)
@JsonBackReference
//@JsonIgnore
private Role role;

之后效果非常好。

“ Field‘ id’没有默认值”,因为您没有在 GeneratedValue注释中声明 GenerationType.IDENTITY

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

这个问题是因为有时您需要再次更新/创建数据库,或者有时如果您在 db 表中添加了字段,但是没有添加实体类,那么它就不能插入任何 null 值或零,所以出现了这个错误。 检查两边.DB 和 Entity 类。

如果字段不可为空,则需要在创建表时指定默认值。重新创建一个 AUTO _ INCREMENT 初始化正确的表,这样 DB 将不需要默认值,因为它将自己生成它,并且永远不会将 NULL 放在那里。

CREATE TABLE Persons (
Personid int NOT NULL AUTO_INCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int,
PRIMARY KEY (Personid)

);

Https://www.w3schools.com/sql/sql_autoincrement.asp

当模型字段与数据库中正确的表字段不匹配时,我在 GCP 云 sql 中得到了这样的错误。 例如: 当模型场为 fieldName
数据库中的表应该有字段 field_name 修正表字段名对我有帮助。

我解决了 < strong >@GeneratedValue (Strategy = GenerationType.AUTO) 改变 @ GeneratedValue (策略 = GenerationType.IDENTITY) 的问题

顺便说一句,我不需要用它来创造,只是:

spring.jpa.hibernate.ddl-auto: update

我解决了类似的问题,当我更改数据库列类型时,并没有添加 auto _  增量。在 alter table 命令中重新添加 auto _  之後(就像在我原始的 table 創建中一樣) ,它工作了

在我的示例中,我没有在 application.properties 文件中添加以下属性:

spring.jpa.database-platform = org.hibernate.dialect.MySQL5InnoDBDialect

并将以下注释添加到我的实体类的 Id 列:

@GeneratedValue(strategy = GenerationType.IDENTITY)

在添加了这个之后,我还从数据库中手动删除了我的表,并再次运行我的项目,为表创建了一个具有所有默认约束的新表。

删除模式是一个非常糟糕的建议。有一个问题,最好是找到并解决它。

在我的案例中,我使用 Envers 创建了一个用于更新条目的审计表。但是,当模式更新时(至少不是 ID 和它的关系) ,这个审计表本身似乎不会得到更新

我只是编辑了违反财产权的审计表格,然后就完成了,一切都恢复正常了。

要查找问题所在,请在 application.properties 文件中打开以下属性

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

这将向您展示它正在尝试执行的 SQL,并希望它能够提供关于实际问题的清晰性。