Hibernate: Id 'Field' không có giá trị mặc định


130

Tôi đang đối mặt với những gì tôi nghĩ là một vấn đề đơn giản với Hibernate, nhưng không thể giải quyết nó (các diễn đàn Hibernate không thể truy cập chắc chắn không giúp ích gì).

Tôi có một lớp học đơn giản tôi muốn tiếp tục, nhưng tiếp tục nhận được:

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 ]

Mã có liên quan cho lớp kiên trì là:

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

Và mã chạy thực tế chỉ đơn giản là:

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

Tôi đã thử một số "chiến lược" trong GeneratedValuechú thích nhưng có vẻ như nó không hoạt động. Khởi tạo idcũng không giúp được gì! (ví dụ Long id = 20L).

Bất cứ ai có thể làm sáng tỏ?

EDIT 2: đã xác nhận: gây rối với @GeneratedValue(strategy = GenerationType.XXX)việc không giải quyết nó

GIẢI QUYẾT: tạo lại cơ sở dữ liệu đã giải quyết vấn đề


Nguồn của Trình xây dựng sử dụng Chuỗi là gì?
Michael Pralow

Xin lỗi, tôi đã bỏ qua điều đó. Chỉ cần khởi tạo trường Chuỗi với giá trị được truyền.
André Chalella

1
Làm thế nào bạn tạo ID ở phía cơ sở dữ liệu?
James McMahon

5
CÁM ƠN ! Không bao giờ nghĩ về việc tạo lại cơ sở dữ liệu là cần thiết khi thay đổi các chiến lược. :-)
Jan Goyvaerts

1
Tôi đã thay đổi GenerationTypetrong @GeneratedValuetừ IDENTITYđể AUTOvà nó làm việc cho tôi. Ngoài ra, bạn có thể có thuộc tính tăng tự động được đặt trong MySQL.
Vishrant

Câu trả lời:


113

Đôi khi, những thay đổi được thực hiện cho mô hình hoặc ORM có thể không phản ánh chính xác trên cơ sở dữ liệu ngay cả sau khi thực hiện SchemaUpdate.

Nếu lỗi thực sự có vẻ thiếu một lời giải thích hợp lý, hãy thử tạo lại cơ sở dữ liệu (hoặc ít nhất là tạo một cơ sở dữ liệu mới) và tạo ra nó SchemaExport.


13
Trong nhiều trường hợp, vấn đề này cũng có thể được giải quyết bằng cách bỏ bảng vi phạm (hoặc bảng), giả sử rằng Hibernate được thiết lập để tự động tạo / quản lý lược đồ DB. Để thả các bảng từ một lược đồ được quản lý, SET foreign_key_checks = 0;là bạn của bạn. Chỉ cần chắc chắn SET foreign_key_checks = 1;khi bạn hoàn thành.
aroth

Tôi gặp vấn đề tương tự và thử với ans của bạn nhưng một lần nữa lại gặp lỗi tương tự tôi không biết lỗi gì ...... Tôi đang sử dụng cơ sở dữ liệu mysql.
Krunal Patel 10/2/2015

56

Nếu bạn muốn MySQL tự động tạo khóa chính thì bạn phải nói với nó khi tạo bảng. Bạn không phải làm điều này trong Oracle.

Trên Khóa chính, bạn phải bao gồm AUTO_INCREMENT. Xem ví dụ dưới đây.

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;  

Đây là thực thể

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

bạn phải sử dụng bản cập nhật trong tài sản hbm2ddl của bạn. thực hiện các thay đổi và cập nhật nó thành Tạo để nó có thể tạo bảng.

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

Nó làm việc cho tôi.


1
Đó là công việc của tôi. Hibernate + Derby DB @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; Và với giá trị createtrong thuộc hbm2ddl.autotính, các thay đổi được áp dụng trong Lược đồ cơ sở dữ liệu của tôi. Cảm ơn rất nhiều ....
Adam M. Gamboa G.

12

Hãy xem GeneratedValuechiến lược của. Nó thường trông giống như:

@GeneratedValue(strategy=GenerationType.IDENTITY)

Chỉ cần đề xuất điều này, hãy thử sử dụng thay vì .AUTO.
James McMahon

Tôi phải kiểm tra nó vào ngày mai, nhưng tôi gần như chắc chắn rằng nó sẽ không sửa nó. Tôi thấy rất nhiều khóa ID sử dụng GenerationType.AUTO. Dù sao, tôi chắc chắn sẽ kiểm tra nó vào ngày mai.
André Chalella

Xác nhận - không giúp đỡ
André Chalella

6

Bỏ bảng từ cơ sở dữ liệu theo cách thủ công và sau đó chạy lại ứng dụng làm việc cho tôi. Trong trường hợp của tôi, bảng không được tạo đúng (có ràng buộc) tôi đoán.


Giải pháp tuyệt vời. Đừng nghĩ như vậy. Cảm ơn
Meir

Chúng ta nên làm điều này khi thực hiện bất kỳ thay đổi nào đối với cột Id hoặc loại thế hệ
Jadda

5

Tôi đã có vấn đề này. Lỗi của tôi là tôi đã đặt các tệp có thể chèn và cập nhật là sai và đang cố gắng đặt trường trong yêu cầu. Trường này được đặt là NON NULL trong DB.

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

Sau này tôi đã thay đổi nó thành - insertable = true, updizable = true

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

Nó hoạt động hoàn hảo sau đó.


cập nhật là đúng theo mặc định
Janac Meena

4

Tôi đến đây vì thông báo lỗi, hóa ra tôi có hai bảng có cùng tên.


Điều tương tự cũng xảy ra với tôi: Bàn làm việc của MySQL chỉ hiển thị một bảng 'người dùng', tuy nhiên, sau khi tôi bỏ tất cả các bảng trong cơ sở dữ liệu, nó đột nhiên hiển thị bảng 'người dùng' khác không hiển thị trước ...
SND

3

Một đề xuất khác là kiểm tra xem bạn có sử dụng loại hợp lệ cho trường được tạo tự động không. Hãy nhớ rằng nó không hoạt động với String, nhưng nó hoạt động với Long:

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

@Constraints.Required
public String contents;

Cú pháp trên đã làm việc để tạo các bảng trong MySQL bằng Hibernate làm nhà cung cấp JPA 2.0.


Thay đổi String thành Long đã sửa lỗi này cho tôi. Cảm ơn
jlars62

3

Tôi đã từng gặp vấn đề tương tự. Tôi đã tìm thấy hướng dẫn Ví dụ về ánh xạ một chiều của Hibernate bằng cách sử dụng Chú thích khóa ngoài và làm theo từng bước như dưới đây:

Tạo bảng cơ sở dữ liệu với tập lệnh này:

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

Đây là các thực thể với các bảng trên

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

Vấn đề đã được giải quyết.

Lưu ý: Khóa chính phải được đặt thành AUTO_INCREMENT


2

Chỉ cần thêm ràng buộc không null

Tôi đã từng gặp vấn đề tương tự. Tôi chỉ thêm ràng buộc không null trong ánh xạ xml. Nó đã làm việc

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

2

Có lẽ đó là vấn đề với lược đồ bảng. thả bảng và chạy lại ứng dụng


1

Ngoài những gì được đề cập ở trên, đừng quên trong khi tạo bảng sql để thực hiện TĂNG TỐC TỰ ĐỘNG như trong ví dụ này

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

Vui lòng kiểm tra xem giá trị Mặc định cho id cột trong bảng cụ thể. Nếu không đặt nó làm mặc định


0

Tôi đã từng gặp vấn đề tương tự. Tôi đã sử dụng một bảng tham gia và tất cả những gì tôi có với một trường id hàng và hai khóa ngoại. Tôi không biết chính xác nguyên nhân nhưng tôi đã làm như sau

  1. Nâng cấp MySQL lên cộng đồng 5.5.13
  2. Đổi tên lớp và bảng
  3. Hãy chắc chắn rằng tôi đã có mã băm và phương thức bằng

    @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

Ngoại lệ tương tự cũng được đưa ra nếu một bảng DB có một cột cũ không được yêu thích.

Ví dụ: attribute_id NOT NULL BIGINT(20),attributeId NOT NULL BIGINT(20),

Sau khi loại bỏ thuộc tính không được sử dụng, trong trường hợp của tôi là hợp đồng , vấn đề đã được giải quyết.


0

Điều này xảy ra với tôi với một @ManyToManymối quan hệ. Tôi đã chú thích một trong các trường trong mối quan hệ với @JoinTable, tôi đã xóa nó và sử dụng mappedBythuộc tính trên @ManyToMany để thay thế.


bạn có thể cung cấp một ví dụ?
Malena T

0

Tôi đã thử mã và trong trường hợp của tôi, mã dưới đây giải quyết vấn đề. Tôi đã không giải quyết đúng lược đồ

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

Hãy cố gắng thêm ,catalog="databasename" giống như tôi đã làm.

,catalog="databasename"

0

Trong trường hợp của tôi, tôi đã thay đổi các bảng vi phạm và trường "id" trong câu hỏi tôi đã tạo nó TỰ ĐỘNG TỰ ĐỘNG, tôi vẫn cần tìm hiểu tại sao vào thời gian triển khai, nó không tạo ra "AUTO_INCREMENT" để tôi phải tự làm điều đó!


0

Cái này thì sao:

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

Tôi hy vọng nó sẽ giúp bạn.


0

Cố gắng thay đổi Longloại đối tượng thành loại longnguyên thủy (nếu sử dụng nguyên thủy là ok cho bạn).

Tôi đã có cùng một vấn đề và thay đổi loại đã giúp tôi.


0

Tôi đã có vấn đề này, do nhầm lẫn tôi đã đặt @Transientchú thích trên thuộc tính cụ thể đó. Trong trường hợp của tôi, lỗi này có ý nghĩa.


0

"Trường 'id' không có giá trị mặc định" vì bạn đã không khai báo GenerationType.IDENTITYtrong GeneratedValueChú thích.

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

0

Vấn đề này là do đôi khi bạn cần cập nhật lại / tạo cơ sở dữ liệu hoặc đôi khi nếu bạn đã thêm trường trong bảng db nhưng không phải là lớp thực thể thì nó không thể chèn bất kỳ giá trị null hoặc 0 nào để xảy ra lỗi này. Vì vậy, kiểm tra cả hai bên.Db và lớp Entity.


0

Khi trường của bạn không thể rỗng, nó yêu cầu một giá trị mặc định được chỉ định khi tạo bảng. Tạo lại một bảng với AUTO_INCREMENT được khởi tạo đúng cách để DB sẽ không yêu cầu giá trị mặc định vì nó sẽ tự tạo và không bao giờ đặt 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


0

tôi đã gặp lỗi như vậy trong GCP đám mây sql khi trường mô hình không khớp với trường bảng chính xác trong db. Ví dụ: khi trong trường mô hình là fieldName
bảng trong db nên có trường field_name Sửa tên trường bảng giúp tôi.


-1

Thêm một phương thức hashCode()vào Entity Bean Class của bạn và thử lại


bạn có thể vui lòng giải thích tại sao?
Raja Anbazhagan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.