我正面临着我认为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)
无法解决问题
已解决:重新创建数据库解决了问题
答案 0 :(得分:95)
有时,即使执行SchemaUpdate
,对模型或ORM所做的更改也可能无法准确反映数据库。
如果错误实际上似乎缺乏合理的解释,请尝试重新创建数据库(或至少创建一个新数据库)并使用SchemaExport
对其进行搭建。
答案 1 :(得分:51)
如果您希望MySQL自动生成主键,则必须在创建表时告诉它。您不必在Oracle中执行此操作。
在主键上,您必须包含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;
}
}
答案 2 :(得分:9)
看看GeneratedValue
的策略。它通常看起来像:
@GeneratedValue(strategy=GenerationType.IDENTITY)
答案 3 :(得分:9)
您必须在hbm2ddl属性中使用update。进行更改并将其更新为Create,以便它可以创建表。
<property name="hbm2ddl.auto">create</property>
它对我有用。
答案 4 :(得分:3)
我遇到了同样的问题。我找到了教程Hibernate One-To-One Mapping Example using Foreign key Annotation,并按照以下步骤进行操作:
使用此脚本创建数据库表:
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
答案 5 :(得分:3)
另一个建议是检查您是否为自动生成的字段使用有效类型。请记住,它不适用于String,但它适用于Long:
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Long id;
@Constraints.Required
public String contents;
以上语法适用于使用Hibernate作为JPA 2.0提供程序在MySQL中生成表。
答案 6 :(得分:2)
由于错误信息,我来到这里,原来我有两张同名的桌子。
答案 7 :(得分:2)
手动从数据库中删除表,然后重新运行对我有用的应用程序。在我的情况下,我猜表创建不正确(有约束)。
答案 8 :(得分:2)
只需添加非空约束
我遇到了同样的问题。我刚刚在xml映射中添加了非空约束。 有效
<set name="phone" cascade="all" lazy="false" >
<key column="id" not-null="true" />
<one-to-many class="com.practice.phone"/>
</set>
答案 9 :(得分:1)
我遇到了这个问题。我的错误是我将可插入和可更新的文件设置为false,并试图在请求中设置该字段。在数据库中,此字段设置为NON NULL。
@ManyToOne
@JoinColumn(name="roles_id", referencedColumnName = "id", insertable = false, updatable = false, nullable=false)
@JsonBackReference
private Role role;
后来我将其更改为-insertable = true,可更新= true
@ManyToOne
@JoinColumn(name="roles_id", referencedColumnName = "id", insertable = true, updatable = true, nullable=false)
@JsonBackReference
//@JsonIgnore
private Role role;
以后效果很好。
答案 10 :(得分:0)
当model字段与db中的正确表字段不匹配时,我在GCP cloud sql中遇到了此类错误。
例:
在模型字段中为fieldName
db中的表应具有字段field_name
固定表字段名称对我有帮助。
答案 11 :(得分:0)
此问题是因为有时您需要再次更新/创建数据库,或者有时如果您已在db表中添加了该字段,但没有添加实体类,则它无法插入任何null值或零,因此出现此错误。 因此,请同时检查side.Db和Entity类。
答案 12 :(得分:0)
“字段'id'没有默认值”,因为您没有在GenerationType.IDENTITY
注释中声明GeneratedValue
。
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
答案 13 :(得分:0)
尝试将Long
对象类型更改为long
基本类型(如果可以使用基本类型)。
我遇到了同样的问题,改变类型帮助了我。
答案 14 :(得分:0)
当您的字段不可为空时,它要求在创建表时指定一个默认值。重新创建具有正确初始化的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)
);
答案 15 :(得分:0)
也许这是表架构的问题。 放下表格,然后重新运行应用程序。
答案 16 :(得分:0)
那呢:
<set name="fieldName" cascade="all">
<key column="id" not-null="true" />
<one-to-many class="com.yourClass"/>
</set>
希望对您有帮助。
答案 17 :(得分:0)
就我而言, 我更改了那个令人讨厌的表和有问题的“ id”字段,将其设置为AUTO_INCREMENT,我仍然需要弄清楚为什么在部署时没有将其设置为“ AUTO_INCREMENT”,所以我必须自己动手!
答案 18 :(得分:0)
我尝试了代码,对于我来说,以下代码解决了该问题。我没有正确地建立模式
{
"_id" : 1,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 6 },
{ "grade" : 85, "mean" : 90, "std" : 4 },
{ "grade" : 85, "mean" : 85, "std" : 6 }
]
}
{
"_id" : 2,
"grades" : [
{ "grade" : 90, "mean" : 75, "std" : 6 },
{ "grade" : 87, "mean" : 90, "std" : 3 },
{ "grade" : 85, "mean" : 85, "std" : 4 }
]
}
db.students2.update(
{ },
{ $set: { "grades.$[elem].mean" : 100 } },
{
multi: true,
arrayFilters: [ { "elem.grade": { $gte: 85 } } ]
}
)
请尝试添加与我相同的@Entity
@Table(name="table"
,catalog="databasename"
)
。
,catalog="databasename"
答案 19 :(得分:0)
除了上面提到的内容外,在创建sql表以制作 AUTO INCREMENT 时,请不要忘记,如本例所示
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
);
答案 20 :(得分:0)
这发生在我身上@ManyToMany
关系。我在@JoinTable
的关系中注释了其中一个字段,我将其删除并使用了@ManyToMany上的mappedBy
属性。
答案 21 :(得分:0)
我遇到了这个问题,我错误地将@Transient
注释放在该特定属性之上。在我的情况下,这个错误是有道理的。
答案 22 :(得分:0)
如果数据库表有一个旧的未删除列,则抛出相同的异常。
例如:
attribute_id NOT NULL BIGINT(20),
和attributeId NOT NULL BIGINT(20),
删除未使用的属性后,在我的情况下 contractId ,问题已解决。
答案 23 :(得分:0)
我遇到了同样的问题。我正在使用一个连接表,我只有一个行id字段和两个外键。我不知道确切的原因,但我做了以下
确保我有哈希码和等于方法
@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;
答案 24 :(得分:0)
请检查特定table.if中列id的默认值是否为默认值
答案 25 :(得分:-1)
将方法hashCode()
添加到您的Entity Bean类并重试