Sospensione: "Il campo" id "non ha un valore predefinito"


130

Sto affrontando quello che penso sia un semplice problema con Hibernate, ma non riesco a risolverlo (essendo i forum di Hibernate irraggiungibili certamente non aiuta).

Ho una lezione semplice che vorrei perseverare, ma continuo a ricevere:

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 ]

Il codice rilevante per la classe persistente è:

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

E il codice corrente è semplicemente chiaro:

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

Ho provato alcune "strategie" all'interno GeneratedValuedell'annotazione ma non sembra funzionare. L'inizializzazione idnon aiuta neanche! (ad es Long id = 20L.).

Qualcuno potrebbe far luce?

EDIT 2: confermato: scherzare con @GeneratedValue(strategy = GenerationType.XXX)non lo risolve

RISOLTO: la ricostruzione del database ha risolto il problema


Qual è la fonte del costruttore che utilizza String?
Michael Pralow,

Mi dispiace, l'ho omesso. Inizializza semplicemente un campo String con il valore passato.
André Chalella,

1
Come si generano gli ID sul lato database?
James McMahon,

5
GRAZIE ! Mai pensato di ricreare il database era necessario quando si cambiavano le strategie. :-)
Jan Goyvaerts

1
Ho cambiato GenerationTypein @GeneratedValueda IDENTITYa AUTOed ha funzionato per me. Inoltre, è possibile impostare la proprietà di incremento automatico impostata in MySQL.
Vishrant,

Risposte:


113

A volte le modifiche apportate al modello o all'ORM potrebbero non riflettere in modo accurato sul database anche dopo l'esecuzione di SchemaUpdate.

Se l'errore sembra in realtà mancare di una spiegazione ragionevole, prova a ricreare il database (o almeno a crearne uno nuovo) e impalcandolo con SchemaExport.


13
In molti casi questo problema può anche essere risolto semplicemente rilasciando la tabella (o le tabelle) offensive, supponendo che Hibernate sia impostato per creare / gestire automaticamente lo schema DB. Per eliminare le tabelle da uno schema gestito, SET foreign_key_checks = 0;è tuo amico. Basta essere sicuri di SET foreign_key_checks = 1;quando hai finito.
aroth

Ho avuto lo stesso problema e prova con il tuo ans, ma di nuovo ho avuto lo stesso errore quale errore faccio non lo so ...... Sto usando il database mysql
Krunal Patel,

56

Se vuoi che MySQL produca automaticamente le chiavi primarie, devi dirlo quando crei la tabella. Non devi farlo in Oracle.

Sulla chiave primaria devi includere AUTO_INCREMENT. Vedi l'esempio sotto.

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;  

Ecco l'entità

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

devi usare update nella tua proprietà hbm2ddl. apporta le modifiche e aggiornalo in Crea in modo che possa creare la tabella.

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

Ha funzionato per me.


1
Per me è un lavoro. Hibernate + Derby DB @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; E con il valore createnella hbm2ddl.autoproprietà le modifiche applicate nel mio schema di database. Grazie mille ....
Adam M. Gamboa G.

12

Dai un'occhiata alla GeneratedValuestrategia di. In genere è simile a:

@GeneratedValue(strategy=GenerationType.IDENTITY)

Sto solo suggerendo questo, prova ad usare questo invece di .AUTO.
James McMahon,

Devo controllarlo domani, ma sono quasi sicuro che non lo risolverà. Vedo molte chiavi ID usando GenerationType.AUTO. Ad ogni modo, mi assicurerò di provarlo domani.
André Chalella,

Confermato - non aiuta
André Chalella il

6

Eliminare manualmente la tabella dal database e quindi rieseguire l'applicazione ha funzionato per me. Nel mio caso la tabella non è stata creata correttamente (con vincoli), credo.


Ottima soluzione Non la pensavo così. Grazie
Meir

Dovremmo farlo quando
apportiamo

5

Ho avuto questo problema. Il mio errore era che avevo impostato i file inseribili e aggiornabili come falsi e stavo cercando di impostare il campo nella richiesta. Questo campo è impostato come NON NULL nel DB.

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

Successivamente l'ho cambiato in - insertable = true, updatable = true

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

Ha funzionato perfettamente dopo.


aggiornabile è vero di default
Janac Meena,

4

Sono venuto qui a causa del messaggio di errore, risulta che avevo due tabelle con lo stesso nome.


La stessa cosa mi è successa in qualche modo: il workbench di MySQL mostrava solo una tabella 'user', tuttavia, dopo che ho lasciato cadere tutte le tabelle nel database, improvvisamente ha mostrato un'altra tabella 'user' che non era visibile prima ...
SND

3

Un altro suggerimento è verificare di utilizzare un tipo valido per il campo generato automaticamente. Ricorda che non funziona con String, ma funziona con Long:

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

@Constraints.Required
public String contents;

La sintassi sopra ha funzionato per la generazione di tabelle in MySQL usando Hibernate come provider JPA 2.0.


La modifica di String in Long ha risolto questo problema per me. Grazie
jlars62 il

3

Ho avuto lo stesso problema. Ho trovato il tutorial Hibernate esempio di mappatura uno-a-uno usando l'annotazione della chiave esterna e l'ho seguito passo dopo passo come di seguito:

Crea una tabella di database con questo script:

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

Ecco le entità con le tabelle sopra

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

Il problema è stato risolto

Avviso: la chiave primaria deve essere impostata su AUTO_INCREMENT


2

Aggiungi solo un vincolo non nullo

Ho avuto lo stesso problema. Ho appena aggiunto un vincolo non nullo nella mappatura XML. Ha funzionato

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

2

Forse questo è il problema con lo schema della tabella. rilasciare la tabella ed eseguire nuovamente l'applicazione.


1

Oltre a quanto menzionato sopra, non dimenticare di creare la tabella sql per aumentare automaticamente come in questo esempio

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

Verifica se il valore predefinito per l'id colonna in particolare table.if non lo rende predefinito


0

Ho avuto lo stesso problema. Stavo usando una tabella di join e tutto ciò che avevo con un campo ID riga e due chiavi esterne. Non conosco l'esatta causa ma ho fatto quanto segue

  1. Aggiornato MySQL alla community 5.5.13
  2. Rinomina la classe e la tabella
  3. Assicurati di avere hashcode e metodi uguali

    @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

La stessa eccezione veniva generata se una tabella DB aveva una vecchia colonna non rimossa.

Ad esempio: attribute_id NOT NULL BIGINT(20),eattributeId NOT NULL BIGINT(20),

Dopo aver rimosso l'attributo non utilizzato, nel mio caso contractId , il problema è stato risolto.


0

Questo mi è successo con una @ManyToManyrelazione. Avevo annotato uno dei campi nella relazione con @JoinTable, l'ho rimosso e invece ho usato l' mappedByattributo su @ManyToMany.


Potete fornire un esempio?
Malena T

0

Ho provato il codice e nel mio caso il codice seguente risolve il problema. Non avevo risolto correttamente lo schema

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

Si prega di provare ad aggiungere ,catalog="databasename" lo stesso che ho fatto.

,catalog="databasename"

0

Nel mio caso, ho modificato le tabelle offensive e il campo "id" in questione. L'ho reso AUTO_INCREMENT, ho ancora bisogno di capire perché in tempo di distribuzione non lo rendesse "AUTO_INCREMENT", quindi devo farlo da solo!


0

Che dire di questo:

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

Spero che ti aiuti.


0

Prova a cambiare il Longtipo di oggetto in tipo longprimitivo (se usare le primitive è giusto per te).

Ho avuto lo stesso problema e cambiare tipo mi ha aiutato.


0

Ho avuto questo problema, per errore avevo posto l' @Transientannotazione sopra quel particolare attributo. Nel mio caso questo errore ha senso.


0

"Field 'id' non ha un valore predefinito" perché non hai dichiarato GenerationType.IDENTITYin GeneratedValueAnnotation.

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

0

Questo problema è dovuto al fatto che a volte è necessario aggiornare / creare nuovamente il database o, a volte, se si è aggiunto il campo nella tabella db ma non una classe di entità, non è possibile inserire alcun valore nullo o zero, quindi si è verificato questo errore. Quindi controlla entrambe le classi side.Db ed Entity.


0

Quando il campo non è nulla, è necessario specificare un valore predefinito per la creazione della tabella. Ricreare una tabella con AUTO_INCREMENT inizializzato correttamente in modo che DB non richieda un valore predefinito poiché lo genererà da solo e non inserirà mai 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

ho riscontrato un errore simile nel sql del cloud GCP quando il campo del modello non corrispondeva al campo corretto della tabella in db. Esempio: quando nel campo modello è presente la fieldName
tabella in db dovrebbe avere campo field_name La tabella di riparazione nome campo mi ha aiutato.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.