Hibernate: "Field 'id' doesn't have a default value"

Viewed 265714

I'm facing what I think is a simple problem with Hibernate, but can't solve it (Hibernate forums being unreachable certainly doesn't help).

I have a simple class I'd like to persist, but keep getting:

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 ]

The relevant code for the persisted class is:

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

And the actual running code is just plain:

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

I tried some "strategies" within the GeneratedValue annotation but it just doesn't seem to work. Initializing id doesn't help either! (eg Long id = 20L).

Could anyone shed some light?

EDIT 2: confirmed: messing with@GeneratedValue(strategy = GenerationType.XXX) doesn't solve it

SOLVED: recreating the database solved the problem

30 Answers

Sometimes changes made to the model or to the ORM may not reflect accurately on the database even after an execution of SchemaUpdate.

If the error actually seems to lack a sensible explanation, try recreating the database (or at least creating a new one) and scaffolding it with SchemaExport.

Take a look at GeneratedValue's strategy. It typically looks something like:

@GeneratedValue(strategy=GenerationType.IDENTITY)

Dropping the table from the database manually and then re-running the application worked for me. In my case table was not created properly(with constraints) I guess.

I had this issue. My mistake was i had set the insertable and updatable fileds as false and was trying to set the field in the request. This field is set as NON NULL in DB.

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

Later I changed it to - insertable = true, updatable = true

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

It worked perfectly later.

I had the same problem. I found the tutorial Hibernate One-To-One Mapping Example using Foreign key Annotation and followed it step by step like below:

Create database table with this 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)   
);

Here is the entities with the above tables

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

The problem was resolved.

Notice: The primary key must be set to AUTO_INCREMENT

Maybe that is the problem with the table schema. drop the table and rerun the application.

In addition to what is mentioned above, do not forget while creating sql table to make the AUTO INCREMENT as in this example

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

When your field is not nullable it requires a default value to be specified on table creation. Recreate a table with AUTO_INCREMENT properly initialized so DB will not require default value since it will generate it by itself and never put NULL there.

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

Please check whether the Default value for the column id in particular table.if not make it as default

I tried the code and in my case the code below solve the issue. I had not settled the schema properly

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

Please try to add ,catalog="databasename" the same as I did.

,catalog="databasename"

In my case, I altered that offending tables and the field "id" in question I made it AUTO_INCREMENT, I still need to figure out why on deployment time it was not making it "AUTO_INCREMENT" so that I have to do it by myself!

What about this:

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

I hope it helps you.

Try to change Long object type to long primitive type (if using primitives is ok for you).

I had the same problem and changing type helped me.

"Field 'id' doesn't have a default value" because you didn't declare GenerationType.IDENTITY in GeneratedValue Annotation.

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

This issue is because sometimes you need to again update/create the database or sometimes if you have added the field in db table but not not entity class then it can not insert any null value or zero so this error came. So check both side.Db and Entity class.

i have got such error in GCP cloud sql when model field didn't match correct table field in db. Example: when in model field is fieldName
table in db should have field field_name Fixing table field name helped me.

I solved it changuing @GeneratedValue(strategy = GenerationType.IDENTITY) by @GeneratedValue(strategy = GenerationType.AUTO)

By the way i didn't need to put it to create, just:

spring.jpa.hibernate.ddl-auto: update

I solved similar problem, when I altered the database column type , and did not add auto_increment. After adding back auto_increment in the alter table command (as in my original table creation) it worked

In my case I have not added the below property in my application.properties file:

spring.jpa.database-platform = org.hibernate.dialect.MySQL5InnoDBDialect

And added the following annotation to my entity class's Id column:

@GeneratedValue(strategy = GenerationType.IDENTITY)

And after adding this I have also drop my table manually from datatbase and run my project again that creates a new table with all default constraints for the table.

To delete just delete your schema is a really bad suggestion. There is a problem and it's best to find and fix it.

In my case I was using Envers this creates an Audit table for when entries are updated. But this audit table does not get updated itself it seems when the schema updates (At least not ID and it's relationships)

I just eddited the audit tables offending property and done. Everything back to normal.

To find what the issue is turn the following properties on in application.properties file

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

This will show you what SQL it is trying to executing and hopefully it will provide clarity on real issue.

Related