Hazırda Bekletme: "Alan 'kimliği' varsayılan bir değere sahip değil"


130

Hazırda bekletme ile ilgili basit bir sorun olduğunu düşündüğüm bir sorunla karşı karşıyayım, ancak çözemiyorum (Hazırda bekletme forumlarının erişilemez olması kesinlikle yardımcı olmuyor).

Kalmak istediğim basit bir dersim var, ancak almaya devam edin:

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 ]

Kalıcı sınıf için ilgili kod şudur:

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

Ve gerçek çalışma kodu basittir:

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

GeneratedValueEk açıklamada bazı "stratejiler" denedim ama işe yaramıyor gibi görünüyor. Başlatma idda yardımcı olmuyor! (örneğin Long id = 20L).

Biri biraz ışık tutabilir mi?

DÜZENLEME 2: onaylandı: uğraşmak @GeneratedValue(strategy = GenerationType.XXX)çözmez

ÇÖZÜLDÜ: veritabanını yeniden oluşturmak sorunu çözdü


String kullanan Constructor'ın kaynağı nedir?
Michael Pralow

Üzgünüm, bunu ihmal ettim. Sadece geçirilen değerle bir String alanını başlatır.
André Chalella

1
Veritabanı tarafında kimlikleri nasıl oluşturuyorsunuz?
James McMahon

5
TEŞEKKÜRLER ! Stratejileri değiştirirken veritabanını yeniden oluşturmanın gerekli olduğunu hiç düşünmedim. :-)
Jan Goyvaerts

1
Değiştim GenerationTypeiçinde @GeneratedValuegelen IDENTITYiçin AUTOve benim için çalıştı. Ayrıca, MySQL'de otomatik artış özelliğini ayarlayabilirsiniz.
Vishrant

Yanıtlar:


113

Bazen modelde veya ORM'de yapılan değişiklikler, çalıştırıldıktan sonra bile veritabanına doğru şekilde yansıtılmayabilir SchemaUpdate.

Hata gerçekten mantıklı bir açıklamadan yoksun görünüyorsa, veritabanını yeniden oluşturmayı (veya en azından yeni bir tane oluşturmayı) ve onu yapılandırmayı deneyin SchemaExport.


13
Çoğu durumda, bu sorun, Hibernate'in DB şemasını otomatik olarak oluşturmak / yönetmek için ayarlandığı varsayılarak, sorun teşkil eden tabloyu (veya tabloları) kaldırarak da çözülebilir. Yönetilen bir şemadan tabloları bırakmak SET foreign_key_checks = 0;sizin dostunuzdur. Sadece SET foreign_key_checks = 1;işin bittiğinde emin ol .
aroth

Aynı sorunu yaşadım ve ans ile denedim ama yine aynı hatayı aldım ne hata yapıyorum bilmiyorum ...... mysql veri tabanını kullanıyorum.
Krunal Patel

56

MySQL'in otomatik olarak birincil anahtarlar üretmesini istiyorsanız, tablo oluştururken bunu söylemeniz gerekir. Bunu Oracle'da yapmak zorunda değilsiniz.

Birincil Anahtar'a eklemeniz gerekir AUTO_INCREMENT. Aşağıdaki örneğe bakın.

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;  

İşte Varlık

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 mülkünüzde güncelleme kullanıyor olmalısınız. değişiklikleri yapın ve tabloyu oluşturabilmesi için Oluştur olarak güncelleyin.

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

Benim için çalıştı.


1
Benim için çalışıyor. Hazırda + Derby DB @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; değerle Ve createiçinde hbm2ddl.autodeğişiklikler Veritabanımdaki Şeması uygulanan mülkiyet. Çok teşekkürler ....
Adam M. Gamboa G.

12

GeneratedValueStratejisine bir göz atın . Genellikle şuna benzer:

@GeneratedValue(strategy=GenerationType.IDENTITY)

Sadece bunu önereceğim, .AUTO yerine bunu kullanmayı deneyin.
James McMahon

Yarın kontrol etmeliyim ama bunun düzeltmeyeceğinden neredeyse eminim. GenerationType.AUTO kullanan çok sayıda kimlik anahtarı görüyorum. Her neyse, yarın test edeceğim.
André Chalella

Onaylandı - yardımcı olmuyor
André Chalella

6

Tabloyu veritabanından manuel olarak düşürmek ve ardından uygulamayı yeniden çalıştırmak benim için çalıştı. Benim durumumda tablo düzgün oluşturulmamış (kısıtlamalarla) sanırım.


Harika çözüm. O şekilde düşünmedim. Teşekkürler
Meir

Bunu, Id sütununda veya Generation
type'da

5

Bu sorunu yaşadım. Benim hatam, eklenebilir ve güncellenebilir dosyaları yanlış olarak ayarlamam ve istekteki alanı ayarlamaya çalışmamdı. Bu alan, DB'de NON NULL olarak ayarlanmıştır.

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

Daha sonra bunu - insertable = true, updatable = true olarak değiştirdim

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

Daha sonra mükemmel çalıştı.


güncellenebilirlik varsayılan olarak doğrudur
Janac Meena

4

Buraya hata mesajı yüzünden geldim, aynı isimli iki tablom olduğu ortaya çıktı.


Aynı şey bir şekilde bana da oldu: MySQL çalışma tezgahı yalnızca bir 'kullanıcı' tablosu gösterdi, ancak veritabanındaki tüm tabloları düşürdükten sonra aniden daha önce görünmeyen başka bir 'kullanıcı' tablosu gösterdi ...
SND

3

Başka bir öneri de, otomatik oluşturulan alan için geçerli bir tür kullanıp kullanmadığınızı kontrol etmektir. String ile çalışmadığını, ancak Long ile çalıştığını unutmayın:

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

@Constraints.Required
public String contents;

Yukarıdaki sözdizimi, bir JPA 2.0 sağlayıcısı olarak Hibernate kullanarak MySQL'de tablolar oluşturmak için çalıştı.


String'i Long olarak değiştirmek bunu benim için düzeltti. Teşekkürler
jlars62

3

Ben de aynı sorunu yaşadım. Yabancı anahtar Ek Açıklamasını kullanarak Hazırda Bekletme Bire Bir Eşleştirme Örneğini buldum ve aşağıdaki gibi adım adım takip ettim:

Bu komut dosyasıyla veritabanı tablosu oluşturun:

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

İşte yukarıdaki tablolara sahip varlıklar

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

Sorun çözüldü.

Uyarı: Birincil anahtar AUTO_INCREMENT olarak ayarlanmalıdır


2

Sadece boş olmayan kısıtlama ekleyin

Ben de aynı sorunu yaşadım. Xml eşlemesine boş olmayan kısıtlama ekledim. İşe yaradı

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

2

Belki de tablo şemasındaki sorun budur. tabloyu bırakın ve uygulamayı yeniden çalıştırın.


1

Yukarıda bahsedilenlere ek olarak, bu örnekte olduğu gibi OTOMATİK ARTIRMA yapmak için sql tablosu oluştururken unutmayın.

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

Lütfen belirli tablodaki sütun kimliği için Varsayılan değerin olup olmadığını kontrol edin. Bunu varsayılan olarak yapmazsanız


0

Ben de aynı sorunu yaşadım. Bir birleştirme tablosu kullanıyordum ve tüm sahip olduğum bir satır kimliği alanı ve iki yabancı anahtar. Tam sebebini bilmiyorum ama şunu yaptım

  1. MySQL, 5.5.13 topluluğuna yükseltildi
  2. Sınıfı ve tabloyu yeniden adlandırın
  3. Hashcode ve equals yöntemlerine sahip olduğumdan emin olun

    @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

Bir DB tablosunda kaldırılmamış eski bir sütun varsa, aynı istisna atılır.

Örneğin: attribute_id NOT NULL BIGINT(20),veattributeId NOT NULL BIGINT(20),

Kullanılmayan özniteliği kaldırdıktan sonra, benim durumumda ContractId , sorun çözüldü.


0

Bu bana bir @ManyToManyilişkiyle oldu. İlişkideki alanlardan birine açıklama ekledim @JoinTable, bunu kaldırdım ve mappedBybunun yerine @ManyToMany'deki özelliği kullandım.


Bir örnek verebilir misiniz?
Malena T

0

Kodu denedim ve benim durumumda aşağıdaki kod sorunu çözdü. Şemayı düzgün bir şekilde halletmemiştim

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

Lütfen ,catalog="databasename" benim yaptığımın aynısını eklemeye çalışın .

,catalog="databasename"

0

Benim durumumda, bu rahatsız edici tabloları değiştirdim ve söz konusu "id" alanını AUTO_INCREMENT yaptım, yine de dağıtım zamanında neden "AUTO_INCREMENT" yapmadığını anlamaya ihtiyacım var, böylece kendi başıma yapmam gerekiyor!


0

Peki buna ne dersin:

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

Umarım size yardımcı olur.


0

LongNesne türünü longilkel tür olarak değiştirmeyi deneyin (ilkellerin kullanılması sizin için uygunsa).

Aynı sorunu yaşadım ve değişen tip bana yardımcı oldu.


0

Bu sorunu yaşadım, yanlışlıkla @Transientbu özelliğin üzerine ek açıklama yerleştirdim . Benim durumumda bu hata mantıklı.


0

Eğer beyan etmedi çünkü "Field 'id' varsayılan bir değeri yoktur" GenerationType.IDENTITYin GeneratedValueEk Açıklamaya.

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

0

Bu sorun, bazen veritabanını yeniden güncellemeniz / oluşturmanız gerekmesi veya bazen alanı db tablosuna eklediyseniz ancak varlık sınıfını eklemiyorsanız, herhangi bir boş değer veya sıfır ekleyemediğinden bu hata geldi. Bu yüzden hem side.Db hem de Entity sınıfını kontrol edin.


0

Alanınız boş değer atanabilir olmadığında, tablo oluştururken varsayılan bir değerin belirtilmesini gerektirir. AUTO_INCREMENT ile uygun şekilde başlatılmış bir tabloyu yeniden oluşturun, böylece DB varsayılan değeri gerektirmez, çünkü onu kendi başına üretir ve oraya asla NULL koymaz.

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 bulut sql'de model alanı db'deki doğru tablo alanıyla eşleşmediğinde böyle bir hata aldım. Örnek: model fieldName
alanındayken field_name db'deki tablo alanı olmalıdır Sabitleme tablosu alan adı bana yardımcı oldu.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.