Hibernate: "Поле" id "не має значення за замовчуванням"


130

Я зіткнувся з тим, що, на мою думку, є проблемою зі сплячкою, але не можу її вирішити (недосяжні форуми, безумовно, не допомагають).

У мене простий клас, який я хотів би наполегливо, але продовжуйте отримувати:

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

Хтось міг пролити світло?

EDIT 2: підтверджено: возитися з цим @GeneratedValue(strategy = GenerationType.XXX)не вирішує

ВИРІШЕНО: відтворення бази даних вирішило проблему


Яке джерело конструктора використовує String?
Майкл Прало

Вибачте, я пропустив це. Просто ініціалізує поле String з переданим значенням.
Андре Шалелла

1
Як ви генеруєте ідентифікатори на стороні бази даних?
Джеймс Макмахон

5
ДЯКУЮ ! Ніколи не замислювався над тим, щоб відтворити базу даних, потрібно було змінювати стратегії. :-)
Ян Гойваерц

1
Я змінив GenerationTypeв @GeneratedValueс IDENTITYк AUTOі він працював на мене. Також у MySQL можна встановити властивість автоматичного збільшення.
Вішрант

Відповіді:


113

Іноді зміни, внесені в модель або в ORM, можуть не відображатись точно в базі даних навіть після виконання SchemaUpdate.

Якщо помилка насправді не має розумного пояснення, спробуйте створити базу даних (або, принаймні, створити нову) та скомпонуйте її SchemaExport.


13
У багатьох випадках цю проблему також можна вирішити, просто скинувши таблицю (або таблиці) порушень, припускаючи, що Hibernate налаштований для автоматичного створення / управління схемою БД. Щоб скинути таблиці з керованої схеми, SET foreign_key_checks = 0;це ваш друг. Просто будьте впевнені, SET foreign_key_checks = 1;коли закінчите.
1212

У мене така ж проблема і спробуйте з вашими ансами, але знову отримала таку ж помилку, яку помилку я роблю, я не знаю ...... Я використовую базу даних mysql.
Krunal Patel

56

Якщо ви хочете, щоб 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;
  }

}

13

ви повинні використовувати оновлення у вашому ресурсі hbm2ddl. внесіть зміни та оновіть її до створення, щоб вона могла створювати таблицю.

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

Це працювало для мене.


1
Це для мене робота. Hibernate + Derby DB @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; І зі значенням createу hbm2ddl.autoвластивості зміни, застосовані в моїй схемі баз даних. Велике спасибі ....
Адам М. Гамбоа Г.

12

Погляньте на GeneratedValueстратегію Росії. Зазвичай це виглядає приблизно так:

@GeneratedValue(strategy=GenerationType.IDENTITY)

Щойно запропонуйте це, спробуйте використовувати це замість .AUTO.
Джеймс Макмахон

Я маю перевірити це завтра, але я майже впевнений, що це не виправить. Я бачу багато ідентифікаційних ключів за допомогою GenerationType.AUTO. У будь-якому разі я обов’язково перевіряю це завтра.
Андре Шалелла

Підтверджено - не допомагає
Андре Шалелла

6

Видалення таблиці з бази даних вручну, а потім повторний запуск програми працював на мене. У моєму випадку таблиця не була створена належним чином (з обмеженнями), мабуть.


Прекрасне рішення. Не думав так. Спасибі
Меїр

Ми повинні це зробити, коли ми внесемо будь-які зміни до стовпця Id або типу генерації
Jadda

5

У мене було це питання. Моя помилка полягала в тому, що я встановив вставлювані та оновлювані файли як помилкові і намагався встановити поле в запиті. Це поле встановлено у БД як NON NULL.

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

Пізніше я змінив його на - inserttable = true, updatetable = true

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

Це спрацювало чудово пізніше.


оновлення вірно за замовчуванням
Janac Meena

4

Я прийшов сюди через повідомлення про помилку, виявляється, у мене були дві таблиці з такою ж назвою.


Зі мною якось трапилося те саме: MySQL workbench показав лише одну таблицю "user", однак, коли я скинув усі таблиці в базу даних, він раптом показав ще одну таблицю "user", яку раніше не було видно ...
SND

3

Ще одна пропозиція - перевірити, чи використовуєте ви дійсний тип для автоматично створеного поля. Пам’ятайте, що він не працює з String, але він працює з Long:

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

@Constraints.Required
public String contents;

Вищевказаний синтаксис працював для генерації таблиць у MySQL, використовуючи Hibernate як постачальник JPA 2.0.


Зміна рядка на Long виправила це для мене. Дякую
jlars62

3

У мене була така ж проблема. Я знайшов підручник зі сплячого режиму зі сплячого режиму "Один на один", використовуючи анотацію із зовнішнім ключем, і дотримувався його крок за кроком, як нижче:

Створіть таблицю бази даних за допомогою цього сценарію:

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


2

Просто додайте ненульове обмеження

У мене була така ж проблема. Щойно я додав ненульове обмеження в xml-картографуванні. Це спрацювало

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

2

Можливо, це проблема зі схемою таблиці. опустити таблицю і запустити програму.


1

Крім того, що було сказано вище, не забувайте , створюючи 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
);

0

Перевірте, чи є значення за замовчуванням для ідентифікатора стовпця в конкретній таблиці


0

У мене була така ж проблема. Я використовував таблицю приєднання, і все, що у мене було, з полем ідентифікатора рядка та двома зовнішніми ключами. Я не знаю точно причину, але я зробив наступне

  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;

0

Це ж виняток було викинуто, якщо в таблиці БД був старий невиправлений стовпець.

Наприклад: attribute_id NOT NULL BIGINT(20),іattributeId NOT NULL BIGINT(20),

Після видалення не використовуваного атрибуту, у моєму випадку ContraId проблема була вирішена.


0

Це сталося зі мною у @ManyToManyстосунках. Я помітив одне з полів у взаємозв'язку з @JoinTable, видалив це і застосував mappedByатрибут на @ManyToMany замість цього.


Чи можете ви навести приклад?
Малена Т

0

Я спробував код, і в моєму випадку код нижче вирішив проблему. Я не розробив схему належним чином

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

Спробуйте додати ,catalog="databasename" те саме, що і я.

,catalog="databasename"

0

У моєму випадку я змінив таблиці порушень та відповідне поле "id". Я зробив це AUTO_INCREMENT, мені все одно потрібно з'ясувати, чому під час розгортання це не робиться "AUTO_INCREMENT", щоб мені довелося це робити самому!


0

Як що до цього:

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

Я сподіваюся, що це вам допоможе.


0

Спробуйте змінити Longтип об'єкта наlong примітивний тип (якщо використання примітивів для вас нормально).

У мене була така ж проблема, і зміна типу мені допомогла.


0

У мене виникло це питання, помилково я поставив @Transientанотацію вище цього атрибута. У моєму випадку ця помилка має сенс.


0

"Поле" id "не має значення за замовчуванням", оскільки ви не оголосили GenerationType.IDENTITYв GeneratedValueАнотації.

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

0

Ця проблема полягає в тому, що іноді вам потрібно знову оновити / створити базу даних або іноді, якщо ви додали поле в таблицю db, але не є класом сутності, то воно не може вставити нульове значення або нуль, тому ця помилка виникла. Тому перевірте обидві side.Db та Entity class.


0

Якщо ваше поле не є нульовим, для створення таблиці потрібно вказати значення за замовчуванням. Відтворіть таблицю з AUTO_INCREMENT належним чином ініціалізованою, тому БД не потребуватиме значення за замовчуванням, оскільки вона генерує її сама і ніколи не ставить туди 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

У мене така помилка в хмарі GCP sql, коли поле моделі не відповідає правильному полі таблиці в db. Приклад: коли в полі моделі fieldName
таблиця в db повинна мати поле field_name Фіксація імені поля таблиці допомогло мені.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.