Hibernate: "Field 'Id' Doesn't Have a Default Value"

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

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.

java.sql.SQLException: Field 'userid' doesn't have a default value?

Hibernate

Hibernate is the interface/link/glue/middleware between your application and the database. It's one of the many framework/libraries, out there, that is making ORM possible and easy. Keyword here is easy, as it makes our lives really simple!

The idea behind Hibernate's naming strategies is to map your POJO(class/model), in your case UserEntity to its respective physical(actual) DB table as seamless as possible(magical, if you will). So, if you name your logical field userId in your POJO, Hibernate needs to be able to map it to the respective physical table column name, example user_id.

Hibernate naming strategies

If you do not explicitly specify the column name(i.e @Column(name = "userid"), Hibernate determines a proper logical name defined by the ImplicitNamingStrategy. If you choose the default/jpa strategy, for basic attributes, it uses the name of the attributes as the logical name. Ideally, all you have to do is:

@Column
private String userId;

So userId is mapped logically to userId implicitly. It further resolves this proper logical name to a physical name, defined by the PhysicalNamingStrategy. By default, Hibernate uses the logical name as the physical name, but the real purpose of the PhysicalNamingStrategy is to say that physical column userId is actually abbreviated to user_id.

Spring Boot

The good news is that Spring Boot provides defaults for both strategies:

spring.jpa.hibernate.naming.physical-strategy defaults to
org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy

spring.jpa.hibernate.naming.implicit-strategy defaults to
org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy

By default, Spring Boot configures the physical naming strategy with CamelCaseToUnderscoresNamingStrategy, this strategy will:

-Change camel-case to snake case(Good if your DB users table column name is user_id.

-Replace dots with underscores.

-Lower-case table names, but it is possible to override that flag if your schema requires it.

You could explicitly(it's Spring Boot's default) add it as a Hibernate property:

@Configuration
public class HibernateConfiguration {

Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.physical_naming_strategy", "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource);
emf.setJpaProperties(hibernateProperties());

Or choose the strategy that best match your use-case. This and this are excellent to learn more about naming strategies.

Easy, long-winded, but clear

The easiest, although not recommended, unless you have no choice(Will you be doing this for all the attributes of all your @Entity classes?), would be to explicitly defined the actual table's column name, in your UserEntity class:

@Column(name = "userid")
private String userId;

How should you name your columns?

Fabricio mentions this: Better yet if you follow the convention of using underscore separated names for your db columns(i.e snake-case) and camel case names for your Java entity properties. This is also Spring conventions:

@Column
private String userId;

DEBUG

During development, you can turn on debugging to see what's really going on by adding this in your application.properties:

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE
spring.jpa.properties.hibernate.format_sql=true

EDIT:
The main issue was that the column was set to @Column(nullable = false), but i will leave all the notes above as it's informative.

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

You can't mix join table with entity

You defined BookedCar as an entity ... do you really need this or you just need a join table to do the many to many join between customer and car ... if you need more columns to be put in the booked car (not the mandatory ID, I mean a column that holds some business) then ok make it an entity, otherwise just make it a join column

If you decided to make it an entity, then you will need one to many relation from each of customer and car to booked_car, and a many to one from booked_car to each of them .... instead of this ManyToMany relation that you are using in car and customer

Spring Hibernate mysql: Field 'id' doesn't have a default value

You mean you want to use auto-increment for the id field ? If yes , you have to specify the strategy of @GeneratedValue to be IDENTITY:

@Entity
public class Test implements Serializable {

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

}

Field 'index_id' doesn't have a default value when trying to use the primary_key as part of composite key in Hibernate

I was able to resolve the issue. I had a one to many relation as given in the Index class

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "index_id")
private Set<Property> properties;

The issue was that I have to do a many to one mapping in the properties class with the index_id.

I changed the Properties class as below.

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;

@Entity
@Table(name = "properties")
public class Property implements Serializable {
private static final long serialVersionUID = 1881413500711441951L;

@Id
@Column(name = "property_key")
private String propertyKey;

@Id
@Column(name = "property_value")
private String propertyValue;

@Id
@ManyToOne
@JoinColumn(name ="index_id")
private Index index;

public Property() {}

public Property(String propertyKey, String propertyValue, Index index) {
this.propertyKey = propertyKey;
this.propertyValue = propertyValue;
this.index = index;
}
}


Related Topics



Leave a reply



Submit