簡體   English   中英

Hibernate:“字段 'id' 沒有默認值”

[英]Hibernate: "Field 'id' doesn't have a default value"

我正面臨一個我認為 Hibernate 的簡單問題,但無法解決(休眠論壇無法訪問當然無濟於事)。

我有一個簡單的 class 我想堅持,但不斷得到:

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 ]

持久化 class 的相關代碼為:

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)並不能解決它

解決:重新創建數據庫解決了問題

有時,即使在執行SchemaUpdate之后,對模型或 ORM 所做的更改也可能無法准確反映在數據庫中。

如果錯誤實際上似乎缺乏合理的解釋,請嘗試重新創建數據庫(或至少創建一個新數據庫)並使用SchemaExport它。

如果您希望 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;
  }

}

看看GeneratedValue的策略。 它通常看起來像:

@GeneratedValue(strategy=GenerationType.IDENTITY)

您必須在 hbm2ddl 屬性中使用更新。 進行更改並將其更新為 Create 以便它可以創建表。

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

它對我有用。

手動從數據庫中刪除表,然后重新運行應用程序對我有用。 在我的情況下,我猜表沒有正確創建(有約束)。

我有這個問題。 我的錯誤是我將可插入和可更新的文件設置為 false,並試圖在請求中設置該字段。 該字段在 DB 中設置為 NON NULL。

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

后來我把它改成了——可插入=真,可更新=真

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

后來效果很好。

我來到這里是因為錯誤消息,原來我有兩個同名的表。

我有同樣的問題。 我找到了教程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

另一個建議是檢查您是否為自動生成的字段使用了有效類型。 請記住,它不適用於 String,但它適用於 Long:

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

@Constraints.Required
public String contents;

上述語法適用於使用 Hibernate 作為 JPA 2.0 提供程序在 MySQL 中生成表。

只需添加非空約束

我有同樣的問題。 我剛剛在 xml 映射中添加了非空約束。 有效

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

也許這就是表模式的問題。 刪除表並重新運行應用程序。

除了上面提到的之外,不要忘記在創建 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
);

當您的字段不可為空時,它需要在創建表時指定默認值。 使用正確初始化的 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

如果數據庫表有一個舊的未刪除列,則會引發相同的異常。

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

刪除未使用的屬性后,在我的情況下為contractId ,問題得到解決。

我遇到了這個問題,我錯誤地將@Transient注釋放在了該特定屬性之上。 在我的情況下,這個錯誤是有道理的。

請檢查特定表中列 id 的默認值是否為默認值。如果不設為默認值

這發生在我身上,是@ManyToMany關系。 我已經注釋了與@JoinTable關系中的一個字段,我刪除了它並使用了 @ManyToMany 上的mappedBy屬性。

我嘗試了代碼,在我的情況下,下面的代碼解決了這個問題。 我沒有正確解決架構

@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原始類型(如果您可以使用原始類型)。

我有同樣的問題,改變類型對我有幫助。

“字段 'id' 沒有默認值”,因為您沒有在GeneratedValue Annotation 中聲明GenerationType.IDENTITY

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

這個問題是因為有時您需要再次更新/創建數據庫,或者有時如果您在 db 表中添加了字段但不是實體類,那么它不能插入任何空值或零,所以這個錯誤來了。 所以檢查 side.Db 和 Entity 類。

當模型字段與數據庫中的正確表字段不匹配時,我在 GCP 雲 sql 中遇到此類錯誤。 示例:當模型字段為fieldName
db 中的表應該有字段field_name修復表字段名稱對我有幫助。

我有同樣的問題。 我正在使用一個連接表,而我所擁有的只有一個行 ID 字段和兩個外鍵。 我不知道確切的原因,但我做了以下

  1. 將 MySQL 升級到社區 5.5.13
  2. 重命名類和表
  3. 確保我有 hashcode 和 equals 方法

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

我通過@GeneratedValue(strategy = GenerationType.AUTO)改變了@GeneratedValue(strategy = GenerationType.IDENTITY)

順便說一句,我不需要把它創建,只是:

spring.jpa.hibernate.ddl-auto: update

當我更改數據庫列類型並且沒有添加 auto_increment 時,我解決了類似的問題。 在 alter table 命令中添加回 auto_increment 后(就像在我的原始表創建中一樣)它起作用了

就我而言,我沒有在 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 ,並希望它能為實際問題提供清晰的信息。

將方法hashCode()添加到您的實體 Bean 類並重試

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM