2009-04-29 9 views
86

Sono di fronte a quello che penso sia un problema semplice con Hibernate, ma non è in grado di risolverlo (i forum di Hibernate sono irraggiungibili certamente non aiutano).Hibernate: "Field 'id' non ha un valore predefinito"

ho una semplice classe che vorrei a persistere, 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 relativo codice 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 in esecuzione reale è solo pianura:

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 del GeneratedValue di annotazione, ma semplicemente non sembra funzionare. L'inizializzazione id non aiuta neanche! (ad es. Long id = 20L).

Qualcuno potrebbe far luce?

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

RISOLTO: ricreare il database ha risolto il problema

+0

Qual è l'origine del Costruttore che utilizza String? –

+0

Mi dispiace, ho omesso questo. Inizializza semplicemente un campo String con il valore passato. –

+0

Stai utilizzando le classi di entità JPA e le chiamate di sessione di Ibernazione, puoi mescolare queste due? –

risposta

78

A volte modifiche apportate al modello o al ORM potrebbero non riflettere accuratamente sul database, anche dopo l'esecuzione di SchemaUpdate.

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

+10

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

+0

Ho avuto lo stesso problema e provo con il tuo ans ma di nuovo ho ricevuto lo stesso errore che errore faccio non lo so ...... Sto usando la base dati mysql. –

7

Date un'occhiata a strategia GeneratedValue s'. Sembra di solito qualcosa di simile:

@GeneratedValue(strategy=GenerationType.IDENTITY) 
+0

Solo per suggerire questo, prova a utilizzare questo invece di .AUTO. –

+0

Devo controllarlo domani, ma sono quasi sicuro che non lo risolverà. Vedo un sacco di chiavi ID utilizzando GenerationType.AUTO. Ad ogni modo, mi assicurerò di testarlo domani. –

+0

Confermato - non aiuta –

-1

Aggiungere un metodo hashCode() al tuo Entity Bean classe e riprovare

+0

potresti spiegare perché? –

0

Si prega di verificare se il valore di default per l'ID di colonna in particolare tavolo.Se av non rendono come predefinito

43

Se si desidera MySQL automaticamente produce chiavi primarie quindi devi dirlo quando crei il tavolo. Non devi farlo in Oracle.

Sulla chiave primaria è necessario includere AUTO_INCREMENT. Vedi l'esempio qui 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'Ente

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

} 
+0

Questo ha funzionato .... –

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. MySQL aggiornato alla comunità 5.5.13
  2. rinominare la classe e la tabella
  3. assicurarsi che ho avuto metodi hashCode e 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; 
    
2

Un altro suggerimento è quello di verificare che si utilizza un tipo valido per il campo generato automaticamente. Ricordate che non funziona con corde, ma funziona con lunghi:

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

@Constraints.Required 
public String contents; 

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

+0

La modifica di String to Long ha risolto questo problema per me. Grazie – jlars62

7

è necessario utilizzare l'aggiornamento nella proprietà hbm2ddl. apportare le modifiche e aggiornarlo per creare in modo che possa creare la tabella.

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

Ha funzionato per me.

+0

rimane lo stesso errore. non è lavoro per me. –

+0

È lavoro per me. Hibernate + Derby DB '@Id @GeneratedValue (strategia = GenerationType.IDENTITY) privata lunga id;' E con il valore 'create' nella proprietà' hbm2ddl.auto' le modifiche applicate nel mio database Schema. Grazie mille .... –

2

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

2

Basta aggiungere vincolo not-null

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> 
1

Ho avuto lo stesso problema. Ho trovato il tutorial Hibernate One-To-One Mapping Example using Foreign key Annotation e seguito passo per passo come di seguito:

Creare tabella del 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 di cui 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 era risolto.

Avviso: La chiave primaria deve essere impostato su auto_increment

0

La stessa eccezione è stata gettata se una tabella DB aveva una antica colonna non rimossi.

Ad esempio: attribute_id NOT NULL BIGINT(20), e attributeId NOT NULL BIGINT(20),

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

0

Ho riscontrato questo problema, per errore ho inserito l'annotazione @Transient sopra quell'attributo specifico. Nel mio caso questo errore ha senso.

0

Mi è successo con una relazione @ManyToMany. Avevo annotato uno dei campi nella relazione con @JoinTable, l'ho rimosso e ho utilizzato l'attributo mappedBy su @ManyToMany.

Problemi correlati