Hibernate:「フィールド 'id'にはデフォルト値がありません」


130

私は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)も解決しない

解決しよう:データベースを再作成すると問題が解決した


文字列を使用したコンストラクタのソースは何ですか?
マイケルプラロウ2009

すみません、それを省略しました。渡された値で文字列フィールドを初期化するだけです。
アンドレ・Chalella

1
データベース側でIDをどのように生成していますか?
James McMahon、

5
どうも !戦略を変更するときに、データベースの再作成が必要になることは考えられませんでした。:-)
Jan Goyvaerts、2012

1
からに変更GenerationType@GeneratedValueIDENTITYところAUTO、うまくいきました。また、MySQLで自動インクリメントプロパティを設定することもできます。
ビシュラント2018

回答:


113

の実行後でも、モデルまたはORMに加えられた変更がデータベースに正確に反映されない場合がありますSchemaUpdate

エラーが実際に適切な説明に欠けていると思われる場合は、データベースを再作成して(または少なくとも新しいデータベースを作成して)、を使用してデータベースをスキャフォールディングしてくださいSchemaExport


13
多くの場合、この問題は、HibernateがDBスキーマを自動的に作成/管理するように設定されていると想定して、問題のあるテーブルを削除することでも解決できます。マネージドスキーマからテーブルを削除するにSET foreign_key_checks = 0;は、あなたの友です。SET foreign_key_checks = 1;完了したら必ず確認してください。
2012

私は同じ問題が発生し、あなたのansを試してみましたが、同じエラーが発生しましたが、私が知っている間違いは何ですか...私はmysqlデータベースを使用しています。
Krunal Patel、2015

56

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

}

13

hbm2ddlプロパティでupdateを使用している必要があります。変更を加え、それをCreateに更新して、テーブルを作成できるようにします。

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

それは私のために働いた。


1
それは私にとって仕事です。Hibernate + Derby DB @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; そしてcreatehbm2ddl.autoプロパティの値を使用して、データベーススキーマに変更が適用されました。どうもありがとう...
アダム・M・ガンボア・G

12

GeneratedValueの戦略を見てみましょう。通常は次のようになります。

@GeneratedValue(strategy=GenerationType.IDENTITY)

これを提案するだけなので、.AUTOの代わりにこれを使用してみてください。
James McMahon、

明日チェックしなければならないが、直らないと確信している。GenerationType.AUTOを使用したIDキーがたくさんあります。とにかく、明日は必ずテストしてみます。
アンドレ・Chalella

確認済み-んではないヘルプ
アンドレ・Chalella

6

データベースからテーブルを手動で削除してから、アプリケーションを再実行するとうまくいきました。私の場合、テーブルは適切に作成されていません(制約付き)と思います。


素晴らしいソリューション。そのように考えていませんでした。ありがとう
Meir

Id列または世代タイプに変更を加える場合、これを行う必要があります
Jadda

5

私はこの問題を抱えていました。私の間違いは、挿入可能で更新可能なフィールドをfalseに設定していて、リクエストにフィールドを設定しようとしていたことです。このフィールドは、DBでは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;

それは後で完全に機能しました。


更新可能はデフォルトでtrueです
Janac Meena

4

エラーメッセージが表示されたため、ここに来ました。同じ名前のテーブルが2つあることがわかりました。


同じことがどういうわけか私にも起こりました。MySQLワークベンチには「ユーザー」テーブルが1つしか表示されませんでしたが、データベース内のすべてのテーブルを削除すると、以前は表示されなかった別の「ユーザー」テーブルが突然表示されました...
SND

3

もう1つの提案は、自動生成フィールドに有効なタイプを使用していることを確認することです。Stringでは機能しませんが、Longでは機能します。

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

@Constraints.Required
public String contents;

上記の構文は、JPA 2.0プロバイダーとしてHibernateを使用してMySQLでテーブルを生成するために機能しました。


文字列をLongに変更すると、これが修正されました。ありがとう
jlars62

3

私も同じ問題を抱えていました。私は、外部キー注釈を使用したチュートリアルHibernate 1対1マッピングの例を見つけ、以下のようにステップバイステップでそれに従いました:

次のスクリプトでデータベーステーブルを作成します。

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に設定する必要があります


2

null以外の制約を追加するだけです

私も同じ問題を抱えていました。XMLマッピングにnot-null制約を追加しました。出来た

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

2

多分それはテーブルスキーマの問題です。テーブルドロップして、アプリケーションを再実行してください。


1

上記に加えて、この例のようにAUTO INCREMENTを作成する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
);

0

特定のテーブルの列IDのデフォルト値かどうかを確認してください。デフォルト値になっていない場合


0

同じ問題がありました。私は結合テーブルを使用していて、行IDフィールドと2つの外部キーをすべて持っていました。正確な原因はわかりませんが、次のことを行いました

  1. MySQLをコミュニティ5.5.13にアップグレードしました
  2. クラスとテーブルの名前を変更する
  3. ハッシュコードと等しいメソッドがあることを確認してください

    @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

DBテーブルに削除されていない古い列がある場合、同じ例外がスローされました。

例: attribute_id NOT NULL BIGINT(20),attributeId NOT NULL BIGINT(20),

使用されていない属性(私の場合、contractId)を削除した後、問題は解決しました。


0

これは私との@ManyToMany関係で起こりました。との関係にあるフィールドの1つに注釈を付けましたが@JoinTable、それを削除して、mappedBy代わりに@ManyToMany の属性を使用しました。


例を提供できますか?
Malena T

0

私はコードを試しました、そして私の場合、以下のコードは問題を解決しました。スキーマを適切に解決していませんでした

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

私と,catalog="databasename" 同じように追加してみてください 。

,catalog="databasename"

0

私の場合、問題のあるテーブルと問題のフィールド「id」をAUTO_INCREMENTに変更しましたが、デプロイ時にそれが「AUTO_INCREMENT」になっていなかった理由を理解する必要があるため、自分で行う必要があります。


0

これはどうですか:

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

お役に立てば幸いです。


0

Longオブジェクトタイプを変更してみてくださいlongプリミティブタイプ(プリミティブを使用しても問題ない場合)。

私は同じ問題を抱えていて、タイプを変更することが助けになりました。


0

私はこの問題を抱えていましたが、誤って@Transientその特定の属性の上に注釈を配置しました。私の場合、このエラーは理にかなっています。


0

「フィールド 'id'にはデフォルト値がありません」というのはGenerationType.IDENTITYGeneratedValueAnnotationで宣言していないためです。

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

0

この問題は、データベースを再度更新/作成する必要がある場合や、エンティティークラスではなくdbテーブルにフィールドを追加した場合にnull値またはゼロを挿入できないため、このエラーが発生するためです。したがって、side.DbとEntityクラスの両方を確認してください。


0

フィールドをnullにできない場合は、テーブルの作成時にデフォルト値を指定する必要があります。AUTO_INCREMENTを適切に初期化してテーブルを再作成します。DBはそれ自体で生成し、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

モデルフィールドがデータベース内の正しいテーブルフィールドと一致しない場合、GCP Cloud SQLでこのようなエラーが発生します。例:モデルフィールドの場合、fieldName
dbのテーブルはフィールドを持つ必要がありますfield_name 固定テーブルフィールド名が役に立ちました。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.