Ruhezustand: "Feld 'id' hat keinen Standardwert"

130

Ich stehe vor einem meiner Meinung nach einfachen Problem mit Hibernate, kann es aber nicht lösen (Hibernate-Foren, die nicht erreichbar sind, helfen sicherlich nicht).

Ich habe eine einfache Klasse, die ich gerne fortsetzen würde, aber immer wieder bekomme:

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 ]

Der relevante Code für die persistierte Klasse lautet:

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

Und der tatsächliche laufende Code ist einfach:

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

Ich habe einige "Strategien" innerhalb der GeneratedValueAnmerkung ausprobiert, aber es scheint einfach nicht zu funktionieren. Initialisierung idhilft auch nicht! (zB Long id = 20L).

Könnte jemand etwas Licht ins Dunkel bringen?

EDIT 2: bestätigt: Durchspielen mit @GeneratedValue(strategy = GenerationType.XXX)löst es nicht

Gelöst: Die Neuerstellung der Datenbank hat das Problem gelöst

André Chalella
quelle
Was ist die Quelle des Konstruktors, der String verwendet?
Michael Pralow
Entschuldigung, das habe ich weggelassen. Initialisiert einfach ein String-Feld mit dem übergebenen Wert.
André Chalella
1
Wie generieren Sie die IDs auf der Datenbankseite?
James McMahon
5
VIELEN DANK ! Beim Ändern der Strategien wurde nie daran gedacht, die Datenbank neu zu erstellen. :-)
Jan Goyvaerts
1
Ich wechselte GenerationTypein @GeneratedValuevon IDENTITYzu AUTOund es funktionierte für mich. Sie können auch die Eigenschaft für die automatische Inkrementierung in MySQL festlegen.
Vishrant

Antworten:

113

Manchmal werden Änderungen am Modell oder am ORM auch nach einer Ausführung von nicht genau in der Datenbank wiedergegeben SchemaUpdate.

Wenn der Fehler tatsächlich keine vernünftige Erklärung zu haben scheint, versuchen Sie, die Datenbank neu zu erstellen (oder zumindest eine neue zu erstellen) und sie mit einem Gerüst zu versehen SchemaExport.

André Chalella
quelle
13
In vielen Fällen kann dieses Problem auch durch einfaches Löschen der betreffenden Tabelle (n) gelöst werden, vorausgesetzt, der Ruhezustand ist so eingerichtet, dass das DB-Schema automatisch erstellt / verwaltet wird. Das Löschen von Tabellen aus einem verwalteten Schema SET foreign_key_checks = 0;ist Ihr Freund. Seien Sie einfach sicher, SET foreign_key_checks = 1;wenn Sie fertig sind.
aroth
Ich habe das gleiche Problem und versuche es mit deiner Ans, aber ich habe wieder den gleichen Fehler, welchen Fehler ich mache, weiß ich nicht ...... Ich benutze die MySQL-Datenbank.
Krunal Patel
56

Wenn MySQL automatisch Primärschlüssel erstellen soll, müssen Sie dies beim Erstellen der Tabelle angeben. Sie müssen dies in Oracle nicht tun.

Auf dem Primärschlüssel müssen Sie angeben AUTO_INCREMENT. Siehe das folgende Beispiel.

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;  

Hier ist die Entität

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

}
Greg Keyes
quelle
13

Sie müssen update in Ihrer hbm2ddl-Eigenschaft verwenden. Nehmen Sie die Änderungen vor und aktualisieren Sie sie auf Erstellen, damit die Tabelle erstellt werden kann.

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

Es hat bei mir funktioniert.

anzie001
quelle
1
Es ist Arbeit für mich. Hibernate + Derby DB @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; Und mit dem Wert createin der hbm2ddl.autoEigenschaft werden die Änderungen in meinem Datenbankschema übernommen. Vielen Dank ....
Adam M. Gamboa G.
12

Schauen Sie sich GeneratedValuedie Strategie an. Es sieht normalerweise so aus:

@GeneratedValue(strategy=GenerationType.IDENTITY)
Steve Kuo
quelle
Versuchen Sie dies einfach anstelle von .AUTO.
James McMahon
Ich muss es morgen überprüfen, aber ich bin mir fast sicher, dass es das nicht beheben wird. Ich sehe viele ID-Schlüssel mit GenerationType.AUTO. Wie auch immer, ich werde es morgen testen.
André Chalella
Bestätigt - hilft nicht
André Chalella
6

Das manuelle Löschen der Tabelle aus der Datenbank und das erneute Ausführen der Anwendung hat bei mir funktioniert. In meinem Fall wurde die Tabelle vermutlich nicht richtig erstellt (mit Einschränkungen).

Sen.
quelle
Tolle Lösung. Habe nicht so gedacht. Danke
Meir
Wir sollten dies tun, wenn wir Änderungen an der
ID-
5

Ich hatte dieses Problem. Mein Fehler war, dass ich die einfügbaren und aktualisierbaren Dateien als falsch festgelegt hatte und versuchte, das Feld in der Anforderung festzulegen. Dieses Feld wird in der Datenbank als NON NULL festgelegt.

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

Später habe ich es geändert in - insertable = true, updatable = true

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

Es hat später perfekt funktioniert.

Kavitha yadav
quelle
Aktualisierbar ist standardmäßig wahr
Janac Meena
4

Ich bin wegen der Fehlermeldung hierher gekommen. Es stellte sich heraus, dass ich zwei Tabellen mit demselben Namen hatte.

Sahan Jayasumana
quelle
Mir ist irgendwie dasselbe passiert: Die MySQL-Workbench zeigte nur eine 'Benutzer'-Tabelle an. Nachdem ich jedoch alle Tabellen in der Datenbank gelöscht hatte, zeigte sie plötzlich eine andere' Benutzer'-Tabelle, die vorher nicht sichtbar war ...
SND
3

Ein weiterer Vorschlag besteht darin, zu überprüfen, ob Sie einen gültigen Typ für das automatisch generierte Feld verwenden. Denken Sie daran, dass es nicht mit String funktioniert, sondern mit Long:

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

@Constraints.Required
public String contents;

Die obige Syntax diente zum Generieren von Tabellen in MySQL unter Verwendung von Hibernate als JPA 2.0-Anbieter.

nize
quelle
Das Ändern von String in Long hat dies für mich behoben. Danke
jlars62
3

Ich hatte das gleiche Problem. Ich fand das Tutorial Beispiel für die Eins-zu-Eins-Zuordnung im Ruhezustand mithilfe der Fremdschlüsselanmerkung und folgte ihm Schritt für Schritt wie folgt:

Erstellen Sie eine Datenbanktabelle mit diesem Skript:

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

Hier sind die Entitäten mit den obigen Tabellen

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

Das Problem wurde behoben.

Hinweis: Der Primärschlüssel muss auf AUTO_INCREMENT gesetzt sein

David Pham
quelle
2

Fügen Sie einfach eine Nicht-Null-Einschränkung hinzu

Ich hatte das gleiche Problem. Ich habe gerade eine Nicht-Null-Einschränkung in der XML-Zuordnung hinzugefügt. Es funktionierte

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

Vielleicht ist das das Problem mit dem Tabellenschema. Löschen Sie die Tabelle und führen Sie die Anwendung erneut aus.

SHIVA
quelle
1

Vergessen Sie nicht, zusätzlich zu den oben genannten Punkten beim Erstellen einer SQL-Tabelle das AUTO INCREMENT wie in diesem Beispiel zu erstellen

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
);
Ahmad Merghany
quelle
0

Bitte überprüfen Sie, ob der Standardwert für die Spalten-ID in einer bestimmten Tabelle nicht standardmäßig festgelegt ist

Arun
quelle
0

Ich hatte das gleiche Problem. Ich benutzte eine Join-Tabelle und alles, was ich hatte, mit einem Zeilen-ID-Feld und zwei Fremdschlüsseln. Ich kenne die genaue Ursache nicht, aber ich habe Folgendes getan

  1. MySQL wurde auf Community 5.5.13 aktualisiert
  2. Benennen Sie die Klasse und die Tabelle um
  3. Stellen Sie sicher, dass ich Hashcode hatte und Methoden gleich

    @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;
Eric
quelle
0

Die gleiche Ausnahme wurde ausgelöst, wenn eine DB-Tabelle eine alte nicht entfernte Spalte hatte.

Zum Beispiel: attribute_id NOT NULL BIGINT(20),undattributeId NOT NULL BIGINT(20),

Nach dem Entfernen des nicht verwendeten Attributs, in meinem Fall contractId , wurde das Problem behoben.

Viktor Reinok
quelle
0

Das ist mir mit einer @ManyToManyBeziehung passiert . Ich hatte eines der Felder in der Beziehung mit kommentiert @JoinTable, das entfernt und mappedBystattdessen das Attribut für @ManyToMany verwendet.

gary69
quelle
Können Sie ein Beispiel geben?
Malena T
0

Ich habe den Code ausprobiert und in meinem Fall löst der folgende Code das Problem. Ich hatte das Schema nicht richtig festgelegt

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

Bitte versuchen Sie ,catalog="databasename" das gleiche wie ich hinzuzufügen .

,catalog="databasename"
Justo Miguel
quelle
0

In meinem Fall habe ich diese fehlerhaften Tabellen und das fragliche Feld "id" geändert. Ich habe es zu AUTO_INCREMENT gemacht. Ich muss immer noch herausfinden, warum es bei der Bereitstellung nicht zu "AUTO_INCREMENT" gemacht wurde, damit ich es selbst tun muss!

Ishimwe Aubain Consolateur
quelle
0

Was ist damit:

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

Ich hoffe es hilft dir.

David Davila
quelle
0

Versuchen Sie, den LongObjekttyp in einen longprimitiven Typ zu ändern (wenn die Verwendung von Primitiven für Sie in Ordnung ist).

Ich hatte das gleiche Problem und der Typwechsel half mir.

Olga
quelle
0

Ich hatte dieses Problem, ich hatte versehentlich eine @TransientAnmerkung über diesem bestimmten Attribut platziert. In meinem Fall ist dieser Fehler sinnvoll.

user158
quelle
0

"Feld 'id' hat keinen Standardwert", weil Sie GenerationType.IDENTITYin GeneratedValueAnnotation nicht deklariert haben .

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
Dracula Oppa
quelle
0

Dieses Problem liegt daran, dass Sie manchmal die Datenbank erneut aktualisieren / erstellen müssen oder manchmal, wenn Sie das Feld in der DB-Tabelle hinzugefügt haben, aber keine Entitätsklasse, keinen Nullwert oder Null einfügen können, sodass dieser Fehler auftrat. Überprüfen Sie also beide side.Db- und Entity-Klassen.

Shubham
quelle
0

Wenn Ihr Feld nicht nullwertfähig ist, muss bei der Tabellenerstellung ein Standardwert angegeben werden. Erstellen Sie eine Tabelle mit ordnungsgemäß initialisiertem AUTO_INCREMENT neu, damit die DB keinen Standardwert benötigt, da sie ihn selbst generiert und dort niemals NULL setzt.

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

Anatoly Leonov
quelle
0

Ich habe einen solchen Fehler in GCP Cloud SQL, wenn das Modellfeld nicht mit dem richtigen Tabellenfeld in DB übereinstimmt. Beispiel: Wenn im Modellfeld eine fieldName
Tabelle in der Datenbank vorhanden ist, sollte mir das Feld Feldname für die field_name Fixierungstabelle geholfen haben.

jhenya-d
quelle
-1

Fügen Sie hashCode()Ihrer Entity Bean-Klasse eine Methode hinzu und wiederholen Sie sie

Tarhack
quelle
Könnten Sie bitte erklären, warum?
Raja Anbazhagan