Hibernate: “Field 'id' tidak memiliki nilai default”


130

Saya menghadapi apa yang saya pikir merupakan masalah sederhana dengan Hibernate, tetapi tidak dapat menyelesaikannya (forum Hibernate yang tidak terjangkau tentu tidak membantu).

Saya memiliki kelas sederhana yang ingin saya pertahankan, tetapi terus dapatkan:

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 ]

Kode yang relevan untuk kelas yang bertahan adalah:

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

Dan kode yang berjalan sebenarnya hanya:

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

Saya mencoba beberapa "strategi" dalam GeneratedValueanotasi tetapi sepertinya tidak berhasil. Inisialisasi idjuga tidak membantu! (misalnya Long id = 20L).

Adakah yang bisa menjelaskan?

EDIT 2: dikonfirmasi: mengacaukan @GeneratedValue(strategy = GenerationType.XXX)tidak menyelesaikannya

ASK: menciptakan kembali database memecahkan masalah


Apa sumber dari Konstruktor menggunakan String?
Michael Pralow

Maaf, saya menghilangkannya. Hanya menginisialisasi bidang String dengan nilai yang diteruskan.
André Chalella

1
Bagaimana Anda membuat ID di sisi database?
James McMahon

5
TERIMA KASIH ! Tidak pernah terpikir untuk membuat ulang basis data diperlukan saat mengubah strategi. :-)
Jan Goyvaerts

1
Aku berubah GenerationTypedalam @GeneratedValuedari IDENTITYke AUTOdan itu bekerja untuk saya. Selain itu, Anda dapat mengatur properti kenaikan otomatis di MySQL.
Vishrant

Jawaban:


113

Terkadang perubahan yang dilakukan pada model atau ORM mungkin tidak mencerminkan akurat pada database bahkan setelah eksekusi SchemaUpdate.

Jika kesalahan tersebut tampaknya tidak memiliki penjelasan yang masuk akal, coba buat ulang basis data (atau setidaknya buat yang baru) dan perancahlah dengan SchemaExport.


13
Dalam banyak kasus masalah ini juga dapat diatasi dengan hanya menjatuhkan tabel (atau tabel) yang menyinggung, dengan anggapan bahwa Hibernate diatur untuk secara otomatis membuat / mengelola skema DB. Untuk menjatuhkan tabel dari skema yang dikelola, SET foreign_key_checks = 0;adalah teman Anda. Pastikan SET foreign_key_checks = 1;saat Anda selesai.
aroth

Saya mendapat masalah yang sama dan mencoba dengan ans Anda tetapi lagi mendapat kesalahan yang sama kesalahan apa yang saya lakukan saya tidak tahu ...... Saya menggunakan basis data mysql.
Krunal Patel

56

Jika Anda ingin MySQL secara otomatis menghasilkan kunci utama maka Anda harus mengatakannya saat membuat tabel. Anda tidak harus melakukan ini di Oracle.

Pada Kunci Utama Anda harus memasukkan AUTO_INCREMENT. Lihat contoh di bawah ini.

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;  

Inilah Entitasnya

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

}

13

Anda harus menggunakan pembaruan di properti hbm2ddl Anda. buat perubahan dan perbarui untuk Membuat sehingga bisa membuat tabel.

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

Ini berhasil untuk saya.


1
Ini bekerja untuk saya. Hibernate + Derby DB @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; Dan dengan nilai createdi hbm2ddl.autoproperti perubahan diterapkan dalam Skema Database saya. Terima kasih banyak ....
Adam M. Gamboa G.

12

Lihatlah GeneratedValuestrategi. Biasanya terlihat seperti:

@GeneratedValue(strategy=GenerationType.IDENTITY)

Hanya akan menyarankan ini, coba gunakan ini daripada .AUTO.
James McMahon

Saya harus memeriksanya besok, tapi saya hampir yakin itu tidak akan memperbaikinya. Saya melihat banyak kunci ID menggunakan GenerationType.AUTO. Bagaimanapun, saya akan memastikan untuk mengujinya besok.
André Chalella

Dikonfirmasi - tidak membantu
André Chalella

6

Menjatuhkan tabel dari database secara manual dan kemudian menjalankan kembali aplikasi bekerja untuk saya. Dalam tabel kasus saya tidak dibuat dengan benar (dengan kendala) saya kira.


Solusi bagus Tidak berpikir seperti itu. Terima kasih
Meir

Kita harus melakukan ini ketika kita membuat perubahan apa pun pada kolom Id atau tipe Generasi
Jadda

5

Saya punya masalah ini. Kesalahan saya adalah saya telah mengatur file yang dapat dimasukkan dan dapat diupdate sebagai salah dan mencoba untuk mengatur bidang dalam permintaan. Bidang ini diatur sebagai NON NULL dalam DB.

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

Kemudian saya mengubahnya menjadi - insertable = true, updatable = true

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

Itu bekerja dengan baik nanti.


updatable benar secara default
Janac Meena

4

Saya datang ke sini karena pesan kesalahan, ternyata saya punya dua tabel dengan nama yang sama.


Hal yang sama terjadi pada saya: meja kerja MySQL hanya memperlihatkan satu tabel 'pengguna', namun, setelah saya menjatuhkan semua tabel dalam database, tiba-tiba muncul tabel 'pengguna' lain yang tidak terlihat sebelumnya ...
SND

3

Saran lain adalah untuk memeriksa bahwa Anda menggunakan tipe yang valid untuk bidang yang dibuat secara otomatis. Ingat bahwa itu tidak bekerja dengan String, tetapi bekerja dengan Long:

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

@Constraints.Required
public String contents;

Sintaks di atas bekerja untuk menghasilkan tabel di MySQL menggunakan Hibernate sebagai penyedia JPA 2.0.


Mengubah String ke Long memperbaiki ini untuk saya. Terima kasih
jlars62

3

Saya memiliki masalah yang sama. Saya menemukan contoh tutorial Hibernate One-To-One Mapping menggunakan Foreign key Annotation dan mengikutinya langkah demi langkah seperti di bawah ini:

Buat tabel database dengan skrip ini:

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

Berikut adalah entitas dengan tabel di atas

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

Masalahnya telah diatasi.

Pemberitahuan: Kunci utama harus disetel ke AUTO_INCREMENT


2

Cukup tambahkan kendala bukan-nol

Saya memiliki masalah yang sama. Saya baru saja menambahkan kendala bukan-nol dalam pemetaan xml. Itu berhasil

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

2

Mungkin itulah masalah dengan skema tabel. jatuhkan meja dan jalankan kembali aplikasi.


1

Selain apa yang disebutkan di atas, jangan lupa saat membuat tabel sql untuk membuat AUTO INCREMENT seperti dalam contoh ini

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

0

Silakan periksa apakah nilai Default untuk id kolom di tabel tertentu. Jika tidak menjadikannya sebagai default


0

Saya memiliki masalah yang sama. Saya menggunakan tabel bergabung dan semua yang saya miliki dengan bidang id baris dan dua kunci asing. Saya tidak tahu persis penyebabnya tetapi saya melakukan yang berikut

  1. Upgrade MySQL ke komunitas 5.5.13
  2. Ganti nama kelas dan tabel
  3. Pastikan saya memiliki kode hash dan sama dengan metode

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

0

Pengecualian yang sama dilemparkan jika tabel DB memiliki kolom lama yang tidak dihapus.

Misalnya: attribute_id NOT NULL BIGINT(20),danattributeId NOT NULL BIGINT(20),

Setelah menghapus atribut yang tidak digunakan, dalam kasus saya contractId , masalahnya teratasi.


0

Ini terjadi pada saya dengan suatu @ManyToManyhubungan. Saya telah mencatat salah satu bidang dalam hubungan dengan @JoinTable, saya menghapusnya dan menggunakan mappedByatribut di @ManyToMany sebagai gantinya.


Bisakah Anda memberikan contoh?
Malena T

0

Saya mencoba kode dan dalam kasus saya kode di bawah ini menyelesaikan masalah. Saya belum menyelesaikan skema dengan benar

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

Silakan coba tambahkan ,catalog="databasename" sama seperti yang saya lakukan.

,catalog="databasename"

0

Dalam kasus saya, saya mengubah tabel yang menyinggung dan bidang "id" dalam pertanyaan saya membuatnya AUTO_INCREMENT, saya masih perlu mencari tahu mengapa pada waktu penempatan itu tidak menjadikannya "AUTO_INCREMENT" sehingga saya harus melakukannya sendiri!


0

Bagaimana dengan ini:

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

Saya harap ini membantu Anda.


0

Cobalah untuk mengubah Longjenis objek ke tipe longprimitif (jika menggunakan primitif ok untuk Anda).

Saya memiliki masalah yang sama dan mengubah tipe membantu saya.


0

Saya memiliki masalah ini, karena keliru saya telah menempatkan @Transientanotasi di atas atribut khusus itu. Dalam kasus saya kesalahan ini masuk akal.


0

"Field 'id' tidak memiliki nilai default" karena Anda tidak mendeklarasikan GenerationType.IDENTITYdalam GeneratedValueAnotasi.

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

0

Masalah ini karena kadang-kadang Anda perlu memperbarui / membuat database lagi atau kadang-kadang jika Anda telah menambahkan bidang dalam tabel db tetapi tidak bukan kelas entitas maka tidak dapat memasukkan nilai nol atau nol sehingga kesalahan ini datang. Jadi periksa kedua sisi side.db dan kelas Entity.


0

Ketika bidang Anda tidak dapat dibatalkan, diperlukan nilai default untuk ditentukan pada pembuatan tabel. Buat ulang tabel dengan AUTO_INCREMENT diinisialisasi dengan benar sehingga DB tidak akan memerlukan nilai default karena ia akan menghasilkannya sendiri dan tidak pernah menempatkan NULL di sana.

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


0

saya mendapatkan kesalahan seperti itu dalam GCP cloud sql ketika bidang model tidak cocok dengan bidang tabel yang benar di db. Contoh: ketika di bidang model adalah fieldName
tabel di db harus ada bidang field_name Memperbaiki nama bidang tabel membantu saya.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.