Спящий режим: поле id не имеет значения по умолчанию

Я столкнулся с простой проблемой, связанной с 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) не решает

РЕШЕНО: воссоздание базы данных решило проблему.


person André Chalella    schedule 29.04.2009    source источник
comment
Каков источник конструктора, использующего String?   -  person Michael Pralow    schedule 30.04.2009
comment
Извините, я пропустил это. Просто инициализирует поле String переданным значением.   -  person André Chalella    schedule 30.04.2009
comment
Вы используете классы сущностей JPA и вызовы сеанса Hibernate, можете ли вы смешать эти два?   -  person James McMahon    schedule 30.04.2009
comment
Как вы генерируете идентификаторы на стороне базы данных?   -  person James McMahon    schedule 30.04.2009
comment
Я бы хотел оставить это в спящем режиме   -  person André Chalella    schedule 01.05.2009
comment
Собственно поле определяется как auto_increment   -  person André Chalella    schedule 01.05.2009
comment
СПАСИБО ! Никогда не думал о воссоздании базы данных при смене стратегии. :-)   -  person Jan Goyvaerts    schedule 03.01.2012
comment
Я изменил GenerationType в @GeneratedValue с IDENTITY на AUTO, и у меня это сработало. Кроме того, в MySQL можно установить свойство автоматического увеличения.   -  person Vishrant    schedule 08.02.2018
comment
Я столкнулся с этой проблемой, потому что забыл назначить AUTO_INCREMENT в определении моей базы данных.   -  person Vikramjit Roy    schedule 22.03.2019


Ответы (26)


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

Если кажется, что ошибке действительно не хватает разумного объяснения, попробуйте воссоздать базу данных (или, по крайней мере, создать новую) и обработать ее с помощью SchemaExport.

person André Chalella    schedule 11.05.2009
comment
Во многих случаях эту проблему также можно решить, просто отбросив проблемную таблицу (или таблицы), предполагая, что Hibernate настроен для автоматического создания / управления схемой БД. SET foreign_key_checks = 0; - ваш друг для удаления таблиц из управляемой схемы. Просто не забудьте SET foreign_key_checks = 1;, когда закончите. - person aroth; 27.08.2012
comment
У меня такая же проблема, и я попробую с вашим ответом, но снова получил ту же ошибку, какую ошибку я делаю, я не знаю ... Я использую базу данных mysql. - person Krunal Patel; 10.02.2015

Если вы хотите, чтобы 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;
  }

}
person Greg Keyes    schedule 28.05.2011
comment
нам нужно сделать первичный ключ как автоинкремент. После внесения этого изменения моя проблема была решена - person Bruce wayne - The Geek Killer; 21.04.2021

Взгляните на стратегию GeneratedValue. Обычно это выглядит примерно так:

@GeneratedValue(strategy=GenerationType.IDENTITY)
person Steve Kuo    schedule 29.04.2009
comment
Просто предлагаю это, попробуйте использовать это вместо .AUTO. - person James McMahon; 30.04.2009
comment
Я должен проверить это завтра, но я почти уверен, что это не исправит. Я вижу много идентификационных ключей, использующих GenerationType.AUTO. В любом случае, я обязательно завтра его протестирую. - person André Chalella; 30.04.2009

вы должны использовать update в свойстве hbm2ddl. внесите изменения и обновите его до Create, чтобы он мог создать таблицу.

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

У меня это сработало.

person anzie001    schedule 10.02.2015
comment
Для меня это работа. Hibernate + Derby DB @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; И со значением create в свойстве hbm2ddl.auto изменения, примененные в моей схеме базы данных. Большое спасибо.... - person Adam M. Gamboa G.; 24.05.2016

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

person Sen    schedule 01.07.2018
comment
Отличное решение. Не думал так. Спасибо - person Meir; 09.07.2018
comment
Мы должны делать это, когда вносим какие-либо изменения в столбец Id или тип генерации. - person Pavan Jadda; 20.11.2018

У меня была эта проблема. Моя ошибка заключалась в том, что я установил для вставляемых и обновляемых полей значение false и пытался установить поле в запросе. Это поле установлено как NON NULL в БД.

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

Позже я изменил его на - insertable = true, updatable = true

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

Позже это сработало отлично.

person Kavitha yadav    schedule 25.04.2019
comment
обновляемый по умолчанию истинен - person Janac Meena; 13.02.2020

Я пришел сюда из-за сообщения об ошибке, оказалось, у меня было две таблицы с одинаковым именем.

person Sahan Jayasumana    schedule 09.11.2015
comment
То же самое как-то случилось со мной: рабочая среда MySQL показала только одну «пользовательскую» таблицу, однако после того, как я отбросил все таблицы в базе данных, он внезапно показал другую «пользовательскую» таблицу, которая не была видна раньше ... - person SND; 06.12.2019

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

Создайте таблицу базы данных с помощью этого скрипта:

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.

person David Pham    schedule 15.10.2016

Другое предложение - проверить, что вы используете допустимый тип для автоматически созданного поля. Помните, что это не работает со String, но работает с Long:

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

@Constraints.Required
public String contents;

Вышеупомянутый синтаксис работал для создания таблиц в MySQL с использованием Hibernate в качестве поставщика JPA 2.0.

person nize    schedule 19.07.2012
comment
Изменение String на Long исправило это для меня. Спасибо - person jlars62; 22.06.2013

Просто добавьте ограничение на непустое значение

У меня такая же проблема. Я просто добавил ограничение на ненулевое значение в сопоставление xml. Это сработало

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

Может быть, проблема в схеме таблицы. перетащите таблицу и перезапустите приложение.

person SHIVA    schedule 14.12.2018

В дополнение к тому, что упомянуто выше, не забудьте при создании таблицы sql сделать АВТОМАТИЧЕСКОЕ УВЕЛИЧЕНИЕ, как в этом примере.

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
);
person Ahmad Merghany    schedule 22.07.2018

Если ваше поле не допускает значения NULL, при создании таблицы необходимо указать значение по умолчанию. Повторно создайте таблицу с правильно инициализированным 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

person Anatoly Leonov    schedule 13.11.2019

Пожалуйста, проверьте, установлено ли значение по умолчанию для идентификатора столбца в конкретной таблице. Если не использовать его по умолчанию

person Arun    schedule 21.12.2010

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

  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;
    
person Eric    schedule 23.06.2011

То же исключение возникало, если в таблице БД был старый неудаленный столбец.

Например: attribute_id NOT NULL BIGINT(20), и attributeId NOT NULL BIGINT(20),.

После удаления неиспользуемого атрибута, в моем случае contractId, проблема была решена.

person Viktor Reinok    schedule 27.02.2017

Это случилось со мной в @ManyToMany отношениях. Я аннотировал одно из полей во взаимосвязи с @JoinTable, я удалил его и вместо этого использовал атрибут mappedBy в @ManyToMany.

person gary69    schedule 20.07.2017
comment
Вы можете привести пример? - person Malena T; 15.03.2018

Я попробовал код, и в моем случае приведенный ниже код решает проблему. Я не правильно установил схему

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

Пожалуйста, попробуйте добавить ,catalog="databasename" то же самое, что и я.

,catalog="databasename"
person Justo Miguel    schedule 29.07.2018

В моем случае я изменил эти оскорбительные таблицы и поле «id», о котором идет речь. Я сделал это AUTO_INCREMENT, мне все еще нужно выяснить, почему во время развертывания он не делал это «AUTO_INCREMENT», так что я должен сделать это сам!

person Ishimwe Aubain Consolateur    schedule 05.12.2018

Что насчет этого:

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

Надеюсь, это тебе поможет.

person David Davila    schedule 05.12.2018

Попробуйте изменить Long тип объекта на long примитивный тип (если использование примитивов вам подходит).

У меня была та же проблема, и смена шрифта помогла мне.

person Olga    schedule 17.01.2019

У меня была эта проблема, я по ошибке поместил аннотацию @Transient над этим конкретным атрибутом. В моем случае эта ошибка имеет смысл.

person user158    schedule 24.06.2017

«Поле 'id' не имеет значения по умолчанию», потому что вы не объявили GenerationType.IDENTITY в GeneratedValue аннотации.

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
person Dracula Oppa    schedule 12.07.2019

Эта проблема возникает из-за того, что иногда вам нужно снова обновить / создать базу данных или иногда, если вы добавили поле в таблицу db, но не класс сущности, тогда он не может вставить какое-либо нулевое значение или ноль, поэтому возникла эта ошибка. Поэтому проверьте оба класса side.Db и Entity.

person Shubham    schedule 05.09.2019

У меня такая ошибка в GCP cloud sql, когда поле модели не соответствует правильному полю таблицы в db. Пример: когда в поле модели находится fieldName
таблица в базе данных должна иметь поле field_name Исправление имени поля таблицы мне помогло.

person jhenya-d    schedule 16.06.2020

Добавьте метод hashCode() в свой класс Entity Bean и повторите попытку.

person tarhack    schedule 16.05.2010
comment
не могли бы вы объяснить почему? - person Raja Anbazhagan; 25.12.2016